PMExtra / sentry-auth-ldap

A Sentry extension to add an LDAP server as an authention source.
Apache License 2.0
27 stars 7 forks source link

MS Active Directory auth #11

Closed AlexSSP closed 1 year ago

AlexSSP commented 1 year ago

I created a clean install sentry cluster in docker from https://github.com/getsentry/self-hosted/tree/23.7.2

My sentry/enhance-image.sh:

requirements=(
'sentry-auth-ldap>=23.6.0'

# Install the dependencies of ldap
apt-get update
apt-get install -y --no-install-recommends build-essential libldap2-dev libsasl2-dev

pip install ${requirements[@]}

# Clean up to shrink the image size
apt-get purge -y --auto-remove build-essential
rm -rf /var/lib/apt/lists/*

My sentry.conf.py:

......
......
......
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType

AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_SERVER_URI = 'ldap://192.168.1.16'
AUTH_LDAP_BIND_DN = 'CN=ldap,OU=Service Accounts,OU=Users,OU=uln,OU=gulliver,OU=gk,DC=gulliver-ul,DC=local'
AUTH_LDAP_BIND_PASSWORD = 'password'
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=gk,dc=gulliver-ul,dc=local",ldap.SCOPE_SUBTREE,"(sAMAccountName=%(user)s)")
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=gk,dc=gulliver-ul,dc=local",ldap.SCOPE_SUBTREE,"(objectClass=group)")
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn")
AUTH_LDAP_REQUIRE_GROUP = "cn=gitlab_users,ou=Groups,ou=uln,ou=gulliver,ou=gc,dc=gulliver-ul,dc=local"
AUTH_LDAP_DENY_GROUP = None
AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
}
AUTH_LDAP_FIND_GROUP_PERMS = False
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600
AUTH_LDAP_DEFAULT_SENTRY_ORGANIZATION = 'ART'
AUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPE = 'member'
AUTH_LDAP_SENTRY_ORGANIZATION_GLOBAL_ACCESS = True
AUTH_LDAP_SENTRY_SUBSCRIBE_BY_DEFAULT = False
SENTRY_MANAGED_USER_FIELDS = ('email', 'first_name', 'last_name', 'password', )
AUTHENTICATION_BACKENDS = AUTHENTICATION_BACKENDS + ('sentry_ldap_auth.backend.SentryLdapBackend',)

LOGGING['disable_existing_loggers'] = False
import logging
logger = logging.getLogger('django_auth_ldap')
logger.setLevel(logging.DEBUG)

My logs when I try to login with AD user or with internal sentry superuser:

docker logs -f sentry-self-hosted-web-1

11:03:05 [INFO] sentry.services.hybrid_cloud: Organization by slug [None] not found
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.8/site-packages/sentry/../sentry_sdk/integrations/django/views.py", line 84, in sentry_wrapped_callback
    return callback(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/sentry/web/frontend/base.py", line 339, in dispatch
    return self.handle(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/sentry/web/frontend/auth_organization_login.py", line 76, in handle
    response = self.handle_basic_auth(request, organization=organization)
  File "/usr/local/lib/python3.8/site-packages/sentry/web/frontend/auth_login.py", line 650, in handle_basic_auth
    elif login_form.is_valid():
  File "/usr/local/lib/python3.8/site-packages/django/forms/forms.py", line 175, in is_valid
    return self.is_bound and not self.errors
  File "/usr/local/lib/python3.8/site-packages/django/forms/forms.py", line 170, in errors
    self.full_clean()
  File "/usr/local/lib/python3.8/site-packages/django/forms/forms.py", line 373, in full_clean
    self._clean_form()
  File "/usr/local/lib/python3.8/site-packages/django/forms/forms.py", line 400, in _clean_form
    cleaned_data = self.clean()
  File "/usr/local/lib/python3.8/site-packages/sentry/web/forms/accounts.py", line 132, in clean
    self.user_cache = authenticate(username=username, password=password)
  File "/usr/local/lib/python3.8/site-packages/django/views/decorators/debug.py", line 42, in sensitive_variables_wrapper
    return func(*func_args, **func_kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 68, in authenticate
    for backend, backend_path in _get_backends(return_tuples=True):
  File "/usr/local/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 27, in _get_backends
    backend = load_backend(backend_path)
  File "/usr/local/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 21, in load_backend
    return import_string(path)()
  File "/usr/local/lib/python3.8/site-packages/django/utils/module_loading.py", line 17, in import_string
    module = import_module(module_path)
  File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'sentry_ldap_auth'
11:03:05 [ERROR] django.request: Internal Server Error: /auth/login/art/ (status_code=500 request=<WSGIRequest: POST '/auth/login/art/'>)
11:03:05 [INFO] sentry.access.api: api.access (method='POST' view='sentry.web.frontend.auth_organization_login.AuthOrganizationLoginView' response=500 user_id='None' is_app='None' token_type='None' is_frontend_request='True' organization_id='None' auth_id='None' path='/auth/login/art/' caller_ip='192.168.203.30' user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0' rate_limited='False' rate_limit_category='None' request_duration_seconds=0.03172492980957031 rate_limit_type='DNE' concurrent_limit='None' concurrent_requests='None' reset_time='None' group='None' limit='None' remaining='None')
PMExtra commented 1 year ago

As your logs said, no module named sentry_ldap_auth, it should be sentry_auth_ldap instead.

AlexSSP commented 1 year ago

But why is the sentry waiting sentry_ldap_auth?

PMExtra commented 1 year ago

Because you specified it in your sentry.conf.py:

AUTHENTICATION_BACKENDS = AUTHENTICATION_BACKENDS + ('sentry_ldap_auth.backend.SentryLdapBackend',)

Search it by yourself, please.