Первый вариант в рамках компании будет регистрация на сайте с django путем авторизации в ldap.
Другой вариант - полная интеграция авторизации ldap в джанго, но тогда все преимущества групп и контроля доступа теряются, если только не получать эту дополнительную информацию от ldap или других источников.
Третий, наиболее гибкий вариант. Отсутствие регистрации. Логиним пользователя - ищем его профиль в auth у Django - если его нет, создаем, если есть - то используем найденный профиль (если пароль в Django не совпадает с ldap паролем - обновляем его).
Давайте пойдем по третьему пути.
Для начала подготавливаем Django. У нас будет расширенный стандартный Django User, так как после авторизации пользователя в ldap мы еще получим его данные с корпоративной базы mssql.
Устанавливаем python-ldap:
- $ sudo apt-get install python-ldap
Прописываем в settings.py:
- LDAP_DOMAIN='mydomain.com'
- LDAP_SERVER='ldaps://%s' % LDAP_DOMAIN #SSL connection
Правим файл auth.py:
- # -*- coding: utf-8 -*-
- from django.conf import settings
- from django.contrib.auth.backends import ModelBackend
- from django.core.exceptions import ImproperlyConfigured
- from django.db.models import get_model
- from social.models import CustomUser
- class CustomUserModelBackend(ModelBackend):
- def get_local_user(self, email, password=None):
- try:
- user = self.user_class.objects.get(email=email.lower())
- if user.check_password(password):
- return user
- else:
- self.exist_user=user#save user for refresh local data
- except self.user_class.DoesNotExist:
- return None
- def get_ldap_refresh_create_user(self, username=None, password=None):
- import ldap, sys
- #create new local user
- if '@' in username:
- #user@domain
- LDAP_USERNAME=username
- username=username.split('@')[0]
- else:
- #user
- LDAP_USERNAME='%s@%s' % (username, settings.LDAP_DOMAIN)
- LDAP_PASSWORD=password
- try:
- # build a client
- ldap_client = ldap.initialize(settings.LDAP_SERVER)
- # perform a synchronous bind
- ldap_client.simple_bind_s(LDAP_USERNAME, LDAP_PASSWORD)
- except ldap.INVALID_CREDENTIALS, e:
- return False
- except ldap.SERVER_DOWN, e:
- return False#@todo raise Validation error
- #lpad auth succes:
- #try to get local user
- user=self.get_local_user(LDAP_USERNAME, password)
- if user:#if we check user in localbase
- return user
- else:#else create new or refresh old pass
- if hasattr(self, 'exist_user'):
- #refresh local auth data from ldap in case of change pass
- self.exist_user.set_password(password)
- self.exist_user.save()#write new pass
- user=self.exist_user
- else:
- user=CustomUser.objects.create_user(username,LDAP_USERNAME,password)
- return user
- def updape_user_info(self, user):
- pass
- def authenticate(self, username=None, password=None):
- #try to auth with ldap
- #and refresh user data in success or create new one if user does not exist
- user=self.get_ldap_refresh_create_user(username, password)
- if user:
- self.updape_user_info(user)#get data from mssql
- return user
- else:
- return None# error ldap auth
- def get_user(self, user_id):
- try:
- return self.user_class.objects.get(pk=user_id)
- except self.user_class.DoesNotExist:
- return None
- @property
- def user_class(self):
- if not hasattr(self, '_user_class'):
- #self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 3))
- self._user_class = CustomUser
- if not self._user_class:
- raise ImproperlyConfigured('Could not get custom user model')
- return self._user_class
Функция updape_user_info на самостоятельное написание, она должна дописывать необходимую расширенную информацию.
ps. прозрачная авторизация в принципе возможна, но только с IE, можете попробовать.
Комментариев нет:
Отправить комментарий