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 %}
-
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()