#python #django #authentication
#python #django #аутентификация
Вопрос:
Я внедрил пользовательский сервер аутентификации для своего проекта Django. Если я запускаю Django локально, получая доступ к производственной базе данных, все работает должным образом. Но если я запускаю то же самое приложение Django на рабочем сервере, происходит сбой.
Вот моя пользовательская аутентификация:
import hashlib
import logging
from django.contrib.auth.models import User
from QAServer import error_codes
from QAServer import exceptions
from QAServer.DataAccess.UserDAO import UserDAO
from QAServer.couchbase_util import ConnectionUtil
import constants as c
logger = logging.getLogger(__name__)
class CouchbaseBackend(object):
_workaround_delimiter = "login "
def authenticate(self, username=None, password=None):
# ## workaround to suppress 401 responses when login is provided in username
# ## -> otherwise problem with browser behaviour!
if username.find(CouchbaseBackend._workaround_delimiter) >= 0:
split = username.split(CouchbaseBackend._workaround_delimiter)
username = split[1]
salt, user = self.get_user(username)
if salt:
pass_hash = hashlib.sha512(password salt).hexdigest()
else:
pass_hash = hashlib.sha256(password).hexdigest()
logger.debug(user.details)
# ## authentication fallback
if user.password == pass_hash:
logger.debug(user.details)
return user
else:
logger.info("### wrong password for user %s ###" % username)
raise exceptions.PermissionError(error_code=error_codes.INVALID_CREDENTIALS_PROVIDED)
def get_user(self, username):
try:
con = ConnectionUtil.get_prod_instance()
dao = UserDAO(con)
cb_user = dao.find_by_username(username)
return self.convert_to_django_user(cb_user)
except User.DoesNotExist as e:
logger.error("### Get User Error (Couchbase Backend Authentication) ###")
logger.error(e)
logger.error("#########################################################")
return None
@staticmethod
def convert_to_django_user(cb_user):
user_name = cb_user[c.USERNAME]
email = cb_user[c.EMAIL]
password = cb_user[c.PASSWORD]
salt = cb_user.get(c.SALT, None)
user = None
try:
user = User(username=user_name, password=password)
user.email = email
user.username = user_name
user.details = cb_user
except Exception, e:
logger.error("### convert user to django user ###")
logger.error(e)
logger.error("###################################")
return salt, user
Часть моих настроек:
AUTHENTICATION_BACKENDS = [
'QASystem.couchbase_backend.CouchbaseBackend'
]
# Application definition
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'corsheaders',
'rest_framework',
'QASystemBackend',
'QASystem'
]
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'QASystem.Authentication.authentication.BasicAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'EXCEPTION_HANDLER': 'QASystem.exception_handler.exception_handler',
'PAGINATE_BY': 10
}
Мой вид входа в систему:
class LoginSet(viewsets.ViewSet):
permission_classes = (AllowAny,)
def __init__(self, *args, **kwargs):
super(LoginSet, self).__init__(*args, **kwargs)
self.user_dao = UserDAO(CBaseUtil.get_prod_instance())
self.token_dao = LoginTokenDAO(CBaseUtil.get_prod_instance())
def login(self, request):
if IsAuthenticated().has_permission(request, None):
user = self.user_dao.find_by_key(request.user.details[m.ID])
logger.info("LoginView::get Login UserID: %s" % request.user.details[m.ID])
response_obj = {
m.USER: user_models.UserModelParser.prepare_response(user),
m.LOGIN_TOKEN: self.token_dao.create_token_for_user(user[m.ID])[0]
}
return Response(response_obj)
else:
logger.error("LoginView::get Invalid Credentials UserID")
raise exceptions.PermissionError(error_code=error_codes.INVALID_CREDENTIALS_PROVIDED)
Здесь, в представлении входа в систему, когда я устанавливаю точку останова, локально отображается правильный объект User в request.user
, но на рабочем месте он продолжает говорить, что это анонимный пользователь.
Часть, в которой происходит сбой, является IsAuthenticated().hasPermission(request, None)
поскольку, по-видимому, разрешение здесь не дано или IsAuthenticated принимает значение False .
Есть идеи, что я мог здесь сделать не так?
Ответ №1:
Я обнаружил, что mod_wsgi вызвал проблему, поскольку он не передает авторизацию по умолчанию.
Обо всех других, с которыми возникает проблема, смотрите этот раздел djangorestframework:
Специфичная конфигурация Apache mod_wsgi
Обратите внимание, что при развертывании с использованием Apache mod_wsgi
заголовок авторизации по умолчанию не передается в приложение WSGI, поскольку предполагается, что аутентификация будет обрабатываться Apache, а не на уровне приложения.
Если вы развертываетесь в Apache и используете любую аутентификацию, не основанную на сеансе, вам нужно будет явно настроить mod_wsgi
передачу требуемых заголовков в приложение. Это можно сделать, указав WSGIPassAuthorization
директиву в соответствующем контексте и установив для нее значение 'On'
.
# this can go in either server config, virtual host, directory or .htaccess
WSGIPassAuthorization On