2016-10-24 3 views
0

내 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) 

, 로컬에서는 정확한 사용자 객체를 request.user에 표시하지만 제작 중에는 계속해서 익명 사용자.

실패한 부분은 IsAuthenticated().hasPermission(request, None)입니다. 여기에 권한이 없거나 IsAuthenticated가 False로 해결되는 것 같습니다.

어떤 생각이든, 내가 잘못 생각한 것일까 요?

답변

1

mod_wsgi가 문제를 일으켰다는 사실을 발견했습니다. 기본적으로 인증을 통과하지 못했기 때문입니다. mod_wsgi를 사용하여 아파치에 배포하는 경우, 인증 헤더가 통과되지 않도록

아파치 mod_wsgi에 특정 구성

참고 :

문제가 발생하는 모든 다른 사람을 위해

, 이것을 djangorestframework의 섹션을 참조 기본적으로 응용 프로그램 수준이 아닌 Apache에서 인증을 처리한다고 가정하므로 WSGI 응용 프로그램에 기본적으로 적용됩니다.

Apache에 배포하고 비 세션 기반 인증을 사용하는 경우 명시 적으로 mod_wsgi을 구성하여 응용 프로그램에 필요한 헤더를 전달해야합니다. 적절한 컨텍스트에서 WSGIPassAuthorization 지시문을 지정하고 'On'으로 설정하면이 작업을 수행 할 수 있습니다.

# this can go in either server config, virtual host, directory or .htaccess 
WSGIPassAuthorization On