Просмотр исходного кода

Merge pull request #4713 from netbox-community/4348-ldap-auth-backend

Closes #4348: Introduce LDAPBackend
Jeremy Stretch 5 лет назад
Родитель
Сommit
67784c0568

+ 4 - 1
docs/configuration/optional-settings.md

@@ -386,7 +386,10 @@ NetBox can be configured to support remote user authentication by inferring user
 
 Default: `'netbox.authentication.RemoteUserBackend'`
 
-Python path to the custom [Django authentication backend](https://docs.djangoproject.com/en/stable/topics/auth/customizing/) to use for external user authentication, if not using NetBox's built-in backend. (Requires `REMOTE_AUTH_ENABLED`.)
+Python path to the custom [Django authentication backend](https://docs.djangoproject.com/en/stable/topics/auth/customizing/) to use for external user authentication. NetBox provides two built-in backends (listed below), though backends may also be provided via other packages.
+
+* `netbox.authentication.RemoteUserBackend`
+* `netbox.authentication.LDAPBackend`
 
 ---
 

+ 9 - 2
docs/installation/5-ldap.md

@@ -36,7 +36,13 @@ Once installed, add the package to `local_requirements.txt` to ensure it is re-i
 
 ## Configuration
 
-Create a file in the same directory as `configuration.py` (typically `netbox/netbox/`) named `ldap_config.py`. Define all of the parameters required below in `ldap_config.py`. Complete documentation of all `django-auth-ldap` configuration options is included in the project's [official documentation](http://django-auth-ldap.readthedocs.io/).
+First, enable the LDAP authentication backend in `configuration.py`. (Be sure to overwrite this definition if it is already set to `RemoteUserBackend`.)
+
+```python
+REMOTE_AUTH_BACKEND = 'netbox.authentication.LDAPBackend'
+```
+
+Next, create a file in the same directory as `configuration.py` (typically `netbox/netbox/`) named `ldap_config.py`. Define all of the parameters required below in `ldap_config.py`. Complete documentation of all `django-auth-ldap` configuration options is included in the project's [official documentation](http://django-auth-ldap.readthedocs.io/).
 
 ### General Server Configuration
 
@@ -145,7 +151,8 @@ logfile = "/opt/netbox/logs/django-ldap-debug.log"
 my_logger = logging.getLogger('django_auth_ldap')
 my_logger.setLevel(logging.DEBUG)
 handler = logging.handlers.RotatingFileHandler(
-   logfile, maxBytes=1024 * 500, backupCount=5)
+    logfile, maxBytes=1024 * 500, backupCount=5
+)
 my_logger.addHandler(handler)
 ```
 

+ 48 - 0
netbox/netbox/authentication.py

@@ -3,6 +3,7 @@ import logging
 from django.conf import settings
 from django.contrib.auth.backends import ModelBackend, RemoteUserBackend as _RemoteUserBackend
 from django.contrib.auth.models import Group
+from django.core.exceptions import ImproperlyConfigured
 from django.db.models import Q
 
 from users.models import ObjectPermission
@@ -132,3 +133,50 @@ class RemoteUserBackend(_RemoteUserBackend):
 
     def has_perm(self, user_obj, perm, obj=None):
         return False
+
+
+class LDAPBackend:
+
+    def __new__(cls, *args, **kwargs):
+        try:
+            import ldap
+            from django_auth_ldap.backend import LDAPBackend as LDAPBackend_, LDAPSettings
+        except ImportError:
+            raise ImproperlyConfigured(
+                "LDAP authentication has been configured, but django-auth-ldap is not installed."
+            )
+
+        try:
+            from netbox import ldap_config
+        except ImportError:
+            raise ImproperlyConfigured(
+                "ldap_config.py does not exist"
+            )
+
+        try:
+            getattr(ldap_config, 'AUTH_LDAP_SERVER_URI')
+        except AttributeError:
+            raise ImproperlyConfigured(
+                "Required parameter AUTH_LDAP_SERVER_URI is missing from ldap_config.py."
+            )
+
+        # Create a new instance of django-auth-ldap's LDAPBackend
+        obj = LDAPBackend_()
+
+        # Read LDAP configuration parameters from ldap_config.py instead of settings.py
+        settings = LDAPSettings()
+        for param in dir(ldap_config):
+            if param.startswith(settings._prefix):
+                setattr(settings, param[10:], getattr(ldap_config, param))
+        obj.settings = settings
+
+        # Optionally disable strict certificate checking
+        if getattr(ldap_config, 'LDAP_IGNORE_CERT_ERRORS', False):
+            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
+
+        # Enable logging for django_auth_ldap
+        ldap_logger = logging.getLogger('django_auth_ldap')
+        ldap_logger.addHandler(logging.StreamHandler())
+        ldap_logger.setLevel(logging.DEBUG)
+
+        return obj

+ 0 - 69
netbox/netbox/settings.py

@@ -378,75 +378,6 @@ LOGIN_URL = '/{}login/'.format(BASE_PATH)
 
 CSRF_TRUSTED_ORIGINS = ALLOWED_HOSTS
 
-
-#
-# LDAP authentication (optional)
-#
-
-try:
-    from netbox import ldap_config as LDAP_CONFIG
-except ImportError:
-    LDAP_CONFIG = None
-
-if LDAP_CONFIG is not None:
-
-    # Check that django_auth_ldap is installed
-    try:
-        import ldap
-        import django_auth_ldap
-    except ImportError:
-        raise ImproperlyConfigured(
-            "LDAP authentication has been configured, but django-auth-ldap is not installed. Remove "
-            "netbox/ldap_config.py to disable LDAP."
-        )
-
-    # Required configuration parameters
-    try:
-        AUTH_LDAP_SERVER_URI = getattr(LDAP_CONFIG, 'AUTH_LDAP_SERVER_URI')
-    except AttributeError:
-        raise ImproperlyConfigured(
-            "Required parameter AUTH_LDAP_SERVER_URI is missing from ldap_config.py."
-        )
-
-    # Optional configuration parameters
-    AUTH_LDAP_ALWAYS_UPDATE_USER = getattr(LDAP_CONFIG, 'AUTH_LDAP_ALWAYS_UPDATE_USER', True)
-    AUTH_LDAP_AUTHORIZE_ALL_USERS = getattr(LDAP_CONFIG, 'AUTH_LDAP_AUTHORIZE_ALL_USERS', False)
-    AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = getattr(LDAP_CONFIG, 'AUTH_LDAP_BIND_AS_AUTHENTICATING_USER', False)
-    AUTH_LDAP_BIND_DN = getattr(LDAP_CONFIG, 'AUTH_LDAP_BIND_DN', '')
-    AUTH_LDAP_BIND_PASSWORD = getattr(LDAP_CONFIG, 'AUTH_LDAP_BIND_PASSWORD', '')
-    AUTH_LDAP_CACHE_TIMEOUT = getattr(LDAP_CONFIG, 'AUTH_LDAP_CACHE_TIMEOUT', 0)
-    AUTH_LDAP_CONNECTION_OPTIONS = getattr(LDAP_CONFIG, 'AUTH_LDAP_CONNECTION_OPTIONS', {})
-    AUTH_LDAP_DENY_GROUP = getattr(LDAP_CONFIG, 'AUTH_LDAP_DENY_GROUP', None)
-    AUTH_LDAP_FIND_GROUP_PERMS = getattr(LDAP_CONFIG, 'AUTH_LDAP_FIND_GROUP_PERMS', False)
-    AUTH_LDAP_GLOBAL_OPTIONS = getattr(LDAP_CONFIG, 'AUTH_LDAP_GLOBAL_OPTIONS', {})
-    AUTH_LDAP_GROUP_SEARCH = getattr(LDAP_CONFIG, 'AUTH_LDAP_GROUP_SEARCH', None)
-    AUTH_LDAP_GROUP_TYPE = getattr(LDAP_CONFIG, 'AUTH_LDAP_GROUP_TYPE', None)
-    AUTH_LDAP_MIRROR_GROUPS = getattr(LDAP_CONFIG, 'AUTH_LDAP_MIRROR_GROUPS', None)
-    AUTH_LDAP_MIRROR_GROUPS_EXCEPT = getattr(LDAP_CONFIG, 'AUTH_LDAP_MIRROR_GROUPS_EXCEPT', None)
-    AUTH_LDAP_PERMIT_EMPTY_PASSWORD = getattr(LDAP_CONFIG, 'AUTH_LDAP_PERMIT_EMPTY_PASSWORD', False)
-    AUTH_LDAP_REQUIRE_GROUP = getattr(LDAP_CONFIG, 'AUTH_LDAP_REQUIRE_GROUP', None)
-    AUTH_LDAP_NO_NEW_USERS = getattr(LDAP_CONFIG, 'AUTH_LDAP_NO_NEW_USERS', False)
-    AUTH_LDAP_START_TLS = getattr(LDAP_CONFIG, 'AUTH_LDAP_START_TLS', False)
-    AUTH_LDAP_USER_QUERY_FIELD = getattr(LDAP_CONFIG, 'AUTH_LDAP_USER_QUERY_FIELD', None)
-    AUTH_LDAP_USER_ATTRLIST = getattr(LDAP_CONFIG, 'AUTH_LDAP_USER_ATTRLIST', None)
-    AUTH_LDAP_USER_ATTR_MAP = getattr(LDAP_CONFIG, 'AUTH_LDAP_USER_ATTR_MAP', {})
-    AUTH_LDAP_USER_DN_TEMPLATE = getattr(LDAP_CONFIG, 'AUTH_LDAP_USER_DN_TEMPLATE', None)
-    AUTH_LDAP_USER_FLAGS_BY_GROUP = getattr(LDAP_CONFIG, 'AUTH_LDAP_USER_FLAGS_BY_GROUP', {})
-    AUTH_LDAP_USER_SEARCH = getattr(LDAP_CONFIG, 'AUTH_LDAP_USER_SEARCH', None)
-
-    # Optionally disable strict certificate checking
-    if getattr(LDAP_CONFIG, 'LDAP_IGNORE_CERT_ERRORS', False):
-        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
-
-    # Prepend LDAPBackend to the authentication backends list
-    AUTHENTICATION_BACKENDS.insert(0, 'django_auth_ldap.backend.LDAPBackend')
-
-    # Enable logging for django_auth_ldap
-    ldap_logger = logging.getLogger('django_auth_ldap')
-    ldap_logger.addHandler(logging.StreamHandler())
-    ldap_logger.setLevel(logging.DEBUG)
-
-
 #
 # Caching
 #