fix(auth): 第三方用户(saml2)登录规则设置无效 (#8648)

* fix: 修复 OpenID、CAS、SAML2登录规则设置无效

* refactor: auth_third_party_required写到一个地方和优化代码结构

* refactor: 优化代码结构

* refactor: 修改变量名称

Co-authored-by: huangzhiwen <zhiwen.huang@fit2cloud.com>
pull/8710/head
fit2bot 2022-08-09 11:24:28 +08:00 committed by GitHub
parent c295f1451a
commit 3951b8b080
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 2 deletions

View File

@ -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

View File

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

View File

@ -0,0 +1,70 @@
{% extends '_base_only_content.html' %}
{% load static %}
{% load i18n %}
{% block html_title %} {{ title }} {% endblock %}
{% block title %} {{ title }}{% endblock %}
{% block content %}
<style>
.alert.alert-msg {
background: #F5F5F7;
}
</style>
<div>
<p>
<div class="alert alert-msg" id="messages">
{% if error %}
{{ error }}
{% else %}
{{ message|safe }}
{% endif %}
</div>
</p>
<div class="row">
{% if has_cancel %}
<div class="col-sm-3">
<a href="{{ cancel_url }}" class="btn btn-default block full-width m-b">
{% trans 'Cancel' %}
</a>
</div>
{% endif %}
<div class="col-sm-3">
<a href="{{ redirect_url }}" class="btn btn-primary block full-width m-b">
{% if confirm_button %}
{{ confirm_button }}
{% else %}
{% trans 'Confirm' %}
{% endif %}
</a>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
var message = ''
var time = '{{ interval }}'
{% if error %}
message = '{{ error }}'
{% else %}
message = '{{ message|safe }}'
{% endif %}
function redirect_page() {
if (time >= 0) {
var msg = message + ' <b>' + time + '</b> ...';
$('#messages').html(msg);
time--;
setTimeout(redirect_page, 1000);
} else {
window.location.href = "{{ redirect_url }}";
}
}
{% if auto_redirect %}
window.onload = redirect_page;
{% endif %}
</script>
{% endblock %}

View File

@ -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

View File

@ -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',
]