perf: Remove unused CAS user exception handling and simplify login view error response (#16380)

* perf: Remove unused CAS user exception handling and simplify login view error response

* perf: position code

---------

Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: Bai <baijiangjie@gmail.com>
This commit is contained in:
fit2bot
2025-12-04 17:49:58 +08:00
committed by GitHub
parent 065bfeda52
commit ba17863892
6 changed files with 18 additions and 62 deletions

View File

@@ -1,51 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import threading
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model
from django_cas_ng.backends import CASBackend as _CASBackend from django_cas_ng.backends import CASBackend as _CASBackend
from common.utils import get_logger from common.utils import get_logger
from ..base import JMSBaseAuthBackend from ..base import JMSBaseAuthBackend
__all__ = ['CASBackend', 'CASUserDoesNotExist'] __all__ = ['CASBackend']
logger = get_logger(__name__) logger = get_logger(__name__)
class CASUserDoesNotExist(Exception):
"""Exception raised when a CAS user does not exist."""
pass
class CASBackend(JMSBaseAuthBackend, _CASBackend): class CASBackend(JMSBaseAuthBackend, _CASBackend):
@staticmethod @staticmethod
def is_enabled(): def is_enabled():
return settings.AUTH_CAS return settings.AUTH_CAS
def authenticate(self, request, ticket, service): def authenticate(self, request, ticket, service):
UserModel = get_user_model() # 这里做个hack ,让父类始终走CAS_CREATE_USER=True的逻辑然后调用 authentication/mixins.py 中的 custom_get_or_create 方法
manager = UserModel._default_manager settings.CAS_CREATE_USER = True
original_get_by_natural_key = manager.get_by_natural_key return super().authenticate(request, ticket, service)
thread_local = threading.local()
thread_local.thread_id = threading.get_ident()
logger.debug(f"CASBackend.authenticate: thread_id={thread_local.thread_id}")
def get_by_natural_key(self, username):
logger.debug(f"CASBackend.get_by_natural_key: thread_id={threading.get_ident()}, username={username}")
if threading.get_ident() != thread_local.thread_id:
return original_get_by_natural_key(username)
try:
user = original_get_by_natural_key(username)
except UserModel.DoesNotExist:
raise CASUserDoesNotExist(username)
return user
try:
manager.get_by_natural_key = get_by_natural_key.__get__(manager, type(manager))
user = super().authenticate(request, ticket=ticket, service=service)
finally:
manager.get_by_natural_key = original_get_by_natural_key
return user

View File

@@ -4,29 +4,22 @@ from django.utils.translation import gettext_lazy as _
from django_cas_ng.views import LoginView from django_cas_ng.views import LoginView
from authentication.backends.base import BaseAuthCallbackClientView from authentication.backends.base import BaseAuthCallbackClientView
from common.utils import FlashMessageUtil from authentication.views.mixins import FlashMessageMixin
from .backends import CASUserDoesNotExist
__all__ = ['LoginView'] __all__ = ['LoginView']
class CASLoginView(LoginView): class CASLoginView(LoginView, FlashMessageMixin):
def get(self, request): def get(self, request):
try: try:
resp = super().get(request) resp = super().get(request)
error_message = getattr(request, 'error_message', '')
if error_message:
response = self.get_failed_response('/', title=_('CAS Error'), msg=error_message)
return response
return resp return resp
except PermissionDenied: except PermissionDenied:
return HttpResponseRedirect('/') return HttpResponseRedirect('/')
except CASUserDoesNotExist as e:
message_data = {
'title': _('User does not exist: {}').format(e),
'error': _(
'CAS login was successful, but no corresponding local user was found in the system, and automatic '
'user creation is disabled in the CAS authentication configuration. Login failed.'),
'interval': 10,
'redirect_url': '/',
}
return FlashMessageUtil.gen_and_redirect_to(message_data)
class CASCallbackClientView(BaseAuthCallbackClientView): class CASCallbackClientView(BaseAuthCallbackClientView):

View File

@@ -46,6 +46,10 @@ def _save_original_get_or_create():
_django_original_get_or_create = _save_original_get_or_create() _django_original_get_or_create = _save_original_get_or_create()
class OnlyAllowExistUserAuthError(Exception):
pass
def _authenticate_context(func): def _authenticate_context(func):
""" """
装饰器:管理 authenticate 函数的执行上下文 装饰器:管理 authenticate 函数的执行上下文
@@ -127,10 +131,6 @@ def _get_backends(return_tuples=False):
return backends return backends
class OnlyAllowExistUserAuthError(Exception):
pass
auth._get_backends = _get_backends auth._get_backends = _get_backends

View File

@@ -381,7 +381,6 @@ class Config(dict):
'CAS_USERNAME_ATTRIBUTE': 'cas:user', 'CAS_USERNAME_ATTRIBUTE': 'cas:user',
'CAS_APPLY_ATTRIBUTES_TO_USER': False, 'CAS_APPLY_ATTRIBUTES_TO_USER': False,
'CAS_RENAME_ATTRIBUTES': {'cas:user': 'username'}, 'CAS_RENAME_ATTRIBUTES': {'cas:user': 'username'},
'CAS_CREATE_USER': True,
'CAS_ORG_IDS': [DEFAULT_ID], 'CAS_ORG_IDS': [DEFAULT_ID],
'AUTH_SSO': False, 'AUTH_SSO': False,
@@ -692,9 +691,9 @@ class Config(dict):
'FTP_FILE_MAX_STORE': 0, 'FTP_FILE_MAX_STORE': 0,
# API 分页 # API 分页
'MAX_LIMIT_PER_PAGE': 10000, # 给导出用 'MAX_LIMIT_PER_PAGE': 10000, # 给导出用
'MAX_PAGE_SIZE': 1000, 'MAX_PAGE_SIZE': 1000,
'DEFAULT_PAGE_SIZE': 200, # 给没有请求分页的用 'DEFAULT_PAGE_SIZE': 200, # 给没有请求分页的用
'LIMIT_SUPER_PRIV': False, 'LIMIT_SUPER_PRIV': False,

View File

@@ -159,7 +159,7 @@ CAS_CHECK_NEXT = lambda _next_page: True
CAS_USERNAME_ATTRIBUTE = CONFIG.CAS_USERNAME_ATTRIBUTE CAS_USERNAME_ATTRIBUTE = CONFIG.CAS_USERNAME_ATTRIBUTE
CAS_APPLY_ATTRIBUTES_TO_USER = CONFIG.CAS_APPLY_ATTRIBUTES_TO_USER CAS_APPLY_ATTRIBUTES_TO_USER = CONFIG.CAS_APPLY_ATTRIBUTES_TO_USER
CAS_RENAME_ATTRIBUTES = CONFIG.CAS_RENAME_ATTRIBUTES CAS_RENAME_ATTRIBUTES = CONFIG.CAS_RENAME_ATTRIBUTES
CAS_CREATE_USER = CONFIG.CAS_CREATE_USER CAS_CREATE_USER = True
# SSO auth # SSO auth
AUTH_SSO = CONFIG.AUTH_SSO AUTH_SSO = CONFIG.AUTH_SSO

View File

@@ -37,11 +37,4 @@ class CASSettingSerializer(serializers.Serializer):
"and the `value` is the JumpServer user attribute name" "and the `value` is the JumpServer user attribute name"
) )
) )
CAS_CREATE_USER = serializers.BooleanField( CAS_ORG_IDS = OrgListField()
required=False, label=_('Create user'),
help_text=_(
'After successful user authentication, if the user does not exist, '
'automatically create the user'
)
)
CAS_ORG_IDS = OrgListField()