From 3951b8b080f19b1e3a41688610bd2cd0a21375dc Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:24:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(auth):=20=E7=AC=AC=E4=B8=89=E6=96=B9?= =?UTF-8?q?=E7=94=A8=E6=88=B7=EF=BC=88saml2=EF=BC=89=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E8=A7=84=E5=88=99=E8=AE=BE=E7=BD=AE=E6=97=A0=E6=95=88=20(#8648?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 修复 OpenID、CAS、SAML2登录规则设置无效 * refactor: auth_third_party_required写到一个地方和优化代码结构 * refactor: 优化代码结构 * refactor: 修改变量名称 Co-authored-by: huangzhiwen --- apps/authentication/middleware.py | 44 +++++++++++- apps/authentication/signal_handlers.py | 4 +- .../auth_fail_flash_message_standalone.html | 70 +++++++++++++++++++ apps/jumpserver/settings/auth.py | 1 + apps/jumpserver/settings/base.py | 1 + 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 apps/authentication/templates/authentication/auth_fail_flash_message_standalone.html diff --git a/apps/authentication/middleware.py b/apps/authentication/middleware.py index b4241f12d..9411b09a6 100644 --- a/apps/authentication/middleware.py +++ b/apps/authentication/middleware.py @@ -1,11 +1,15 @@ import base64 -from django.shortcuts import redirect, reverse +from django.shortcuts import redirect, reverse, render from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse from django.conf import settings +from django.utils.translation import ugettext as _ +from django.contrib.auth import logout as auth_logout +from apps.authentication import mixins from common.utils import gen_key_pair +from common.utils import get_request_ip class MFAMiddleware: @@ -13,6 +17,7 @@ class MFAMiddleware: 这个 中间件 是用来全局拦截开启了 MFA 却没有认证的,如 OIDC, CAS,使用第三方库做的登录,直接 login 了, 所以只能在 Middleware 中控制 """ + def __init__(self, get_response): self.get_response = get_response @@ -42,6 +47,43 @@ class MFAMiddleware: return redirect(url) +class ThirdPartyLoginMiddleware(mixins.AuthMixin): + """OpenID、CAS、SAML2登录规则设置验证""" + + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + response = self.get_response(request) + # 没有认证过,证明不是从 第三方 来的 + if request.user.is_anonymous: + return response + if not request.session.get('auth_third_party_required'): + return response + ip = get_request_ip(request) + try: + self._check_login_acl(request.user, ip) + except Exception as e: + auth_logout(request) + context = { + 'title': _('Authentication failed'), + 'message': _('Authentication failed (before login check failed): {}').format(e), + 'interval': 10, + 'redirect_url': reverse('authentication:login'), + 'auto_redirect': True, + } + response = render(request, 'authentication/auth_fail_flash_message_standalone.html', context) + else: + guard_url = reverse('authentication:login-guard') + args = request.META.get('QUERY_STRING', '') + if args: + guard_url = "%s?%s" % (guard_url, args) + response = redirect(guard_url) + finally: + request.session.pop('auth_third_party_required', '') + return response + + class SessionCookieMiddleware(MiddlewareMixin): @staticmethod diff --git a/apps/authentication/signal_handlers.py b/apps/authentication/signal_handlers.py index 7fc1fc6b5..68d8c0531 100644 --- a/apps/authentication/signal_handlers.py +++ b/apps/authentication/signal_handlers.py @@ -6,6 +6,7 @@ from django.core.cache import cache from django.dispatch import receiver from django_cas_ng.signals import cas_user_authenticated +from apps.jumpserver.settings.auth import AUTHENTICATION_BACKENDS_THIRD_PARTY from authentication.backends.oidc.signals import ( openid_user_login_failed, openid_user_login_success ) @@ -28,7 +29,8 @@ def on_user_auth_login_success(sender, user, request, **kwargs): and user.mfa_enabled \ and not request.session.get('auth_mfa'): request.session['auth_mfa_required'] = 1 - + if request.session.get('auth_backend') in AUTHENTICATION_BACKENDS_THIRD_PARTY: + request.session['auth_third_party_required'] = 1 # 单点登录,超过了自动退出 if settings.USER_LOGIN_SINGLE_MACHINE_ENABLED: lock_key = 'single_machine_login_' + str(user.id) diff --git a/apps/authentication/templates/authentication/auth_fail_flash_message_standalone.html b/apps/authentication/templates/authentication/auth_fail_flash_message_standalone.html new file mode 100644 index 000000000..61b431b9a --- /dev/null +++ b/apps/authentication/templates/authentication/auth_fail_flash_message_standalone.html @@ -0,0 +1,70 @@ +{% extends '_base_only_content.html' %} +{% load static %} +{% load i18n %} +{% block html_title %} {{ title }} {% endblock %} +{% block title %} {{ title }}{% endblock %} + +{% block content %} + +
+

+

+ {% if error %} + {{ error }} + {% else %} + {{ message|safe }} + {% endif %} +
+

+ + +
+{% endblock %} + +{% block custom_foot_js %} + +{% endblock %} + diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index 803315f9c..9ab01b6a1 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -205,6 +205,7 @@ AUTHENTICATION_BACKENDS = [ AUTH_BACKEND_AUTH_TOKEN, AUTH_BACKEND_SSO, AUTH_BACKEND_TEMP_TOKEN ] +AUTHENTICATION_BACKENDS_THIRD_PARTY = [AUTH_BACKEND_OIDC_CODE, AUTH_BACKEND_CAS, AUTH_BACKEND_SAML2] ONLY_ALLOW_EXIST_USER_AUTH = CONFIG.ONLY_ALLOW_EXIST_USER_AUTH ONLY_ALLOW_AUTH_FROM_SOURCE = CONFIG.ONLY_ALLOW_AUTH_FROM_SOURCE diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 547aa9c1b..a65266a1f 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -109,6 +109,7 @@ MIDDLEWARE = [ 'authentication.backends.oidc.middleware.OIDCRefreshIDTokenMiddleware', 'authentication.backends.cas.middleware.CASMiddleware', 'authentication.middleware.MFAMiddleware', + 'authentication.middleware.ThirdPartyLoginMiddleware', 'authentication.middleware.SessionCookieMiddleware', 'simple_history.middleware.HistoryRequestMiddleware', ]