diff --git a/apps/authentication/templates/authentication/login.html b/apps/authentication/templates/authentication/login.html index 67a627c92..751c6f341 100644 --- a/apps/authentication/templates/authentication/login.html +++ b/apps/authentication/templates/authentication/login.html @@ -232,11 +232,11 @@ -{% if not origin_is_allowed %} +{% if error_origin %}
配置文件存在问题,无法完成登录,请联系管理员解决,或查看最新更新说明
Configuration file has problems and cannot be logged in. Please contact the administrator
- - {{ origin }} - + - {{ error_origin }} -
{% endif %}
@@ -321,8 +321,7 @@
-
diff --git a/apps/authentication/views/login.py b/apps/authentication/views/login.py index 748d1e759..5eb95e4e9 100644 --- a/apps/authentication/views/login.py +++ b/apps/authentication/views/login.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import datetime import os from typing import Callable +from urllib.parse import urlparse from django.conf import settings from django.contrib.auth import BACKEND_SESSION_KEY @@ -18,7 +19,7 @@ from django.urls import reverse_lazy from django.utils.decorators import method_decorator from django.utils.translation import gettext as _, get_language from django.views.decorators.cache import never_cache -from django.views.decorators.csrf import csrf_protect +from django.views.decorators.csrf import csrf_exempt from django.views.decorators.debug import sensitive_post_parameters from django.views.generic.base import TemplateView, RedirectView from django.views.generic.edit import FormView @@ -40,6 +41,7 @@ __all__ = [ class UserLoginContextMixin: get_user_mfa_context: Callable request: HttpRequest + error_origin: str def get_support_auth_methods(self): auth_methods = [ @@ -134,19 +136,8 @@ class UserLoginContextMixin: count += 1 return count - def origin_is_allowed(self): - from urllib.parse import urlparse - http_referer = self.request.META.get('HTTP_REFERER') - try: - referer = urlparse(http_referer) - except ValueError: - return False, None - allowed_domains = settings.ALLOWED_DOMAINS - return referer.netloc in allowed_domains, referer.netloc - def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - origin_allowed, origin = self.origin_is_allowed() context.update({ 'demo_mode': os.environ.get("DEMO_MODE"), 'auth_methods': self.get_support_auth_methods(), @@ -154,19 +145,19 @@ class UserLoginContextMixin: 'current_lang': self.get_current_lang(), 'forgot_password_url': self.get_forgot_password_url(), 'extra_fields_count': self.get_extra_fields_count(context), - 'origin_is_allowed': origin_allowed, - 'origin': origin, + 'error_origin': self.error_origin, **self.get_user_mfa_context(self.request.user) }) return context @method_decorator(sensitive_post_parameters(), name='dispatch') -@method_decorator(csrf_protect, name='dispatch') @method_decorator(never_cache, name='dispatch') +@method_decorator(csrf_exempt, name='dispatch') class UserLoginView(mixins.AuthMixin, UserLoginContextMixin, FormView): redirect_field_name = 'next' template_name = 'authentication/login.html' + error_origin = '' def redirect_third_party_auth_if_need(self, request): # show jumpserver login page if request http://{JUMP-SERVER}/?admin=1 @@ -215,11 +206,32 @@ class UserLoginView(mixins.AuthMixin, UserLoginContextMixin, FormView): request.session.set_test_cookie() return super().get(request, *args, **kwargs) + def check_origin_is_allowed(self, request): + http_referer = request.META.get('HTTP_REFERER') + if not http_referer: + return False, '' + referer = urlparse(http_referer) + netloc = str(referer.netloc) + allowed_domains = settings.ALLOWED_DOMAINS + allowed = netloc in allowed_domains + + if not allowed and ':' not in netloc: + suffix = ':80' if referer.scheme == 'http' else ':443' + netloc += suffix + allowed = netloc in allowed_domains + return allowed, netloc + def form_valid(self, form): if not self.request.session.test_cookie_worked(): form.add_error(None, _("Login timeout, please try again.")) return self.form_invalid(form) + origin_allowed, origin = self.check_origin_is_allowed(self.request) + if not origin_allowed: + self.error_origin = origin + form.add_error(None, '当前域不在信任域中,拒绝登录') + return self.form_invalid(form) + # https://docs.djangoproject.com/en/3.1/topics/http/sessions/#setting-test-cookies self.request.session.delete_test_cookie()