perf: 优化登录页面提示判断,可能没有端口

perf: 修改 login 检测
pull/11353/head
ibuler 2023-08-18 17:09:10 +08:00
parent b2d9670721
commit 4315cbe6d0
2 changed files with 30 additions and 19 deletions

View File

@ -232,11 +232,11 @@
</head> </head>
<body> <body>
{% if not origin_is_allowed %} {% if error_origin %}
<div class='alert alert-danger error-info'> <div class='alert alert-danger error-info'>
配置文件存在问题无法完成登录请联系管理员解决或查看最新更新说明 <br/> 配置文件存在问题无法完成登录请联系管理员解决或查看最新更新说明 <br/>
Configuration file has problems and cannot be logged in. Please contact the administrator <br/> Configuration file has problems and cannot be logged in. Please contact the administrator <br/>
- {{ origin }} - - {{ error_origin }} -
</div> </div>
{% endif %} {% endif %}
<div class="login-content extra-fields-{{ extra_fields_count }}"> <div class="login-content extra-fields-{{ extra_fields_count }}">
@ -321,8 +321,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<button type="submit" class="btn btn-transparent" onclick="doLogin();return false;" <button type="submit" class="btn btn-transparent" onclick="doLogin();return false;">
{% if not origin_is_allowed %} disabled {% endif %}>
{% trans 'Login' %} {% trans 'Login' %}
</button> </button>
</div> </div>

View File

@ -6,6 +6,7 @@ from __future__ import unicode_literals
import datetime import datetime
import os import os
from typing import Callable from typing import Callable
from urllib.parse import urlparse
from django.conf import settings from django.conf import settings
from django.contrib.auth import BACKEND_SESSION_KEY 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.decorators import method_decorator
from django.utils.translation import gettext as _, get_language from django.utils.translation import gettext as _, get_language
from django.views.decorators.cache import never_cache 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.decorators.debug import sensitive_post_parameters
from django.views.generic.base import TemplateView, RedirectView from django.views.generic.base import TemplateView, RedirectView
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
@ -40,6 +41,7 @@ __all__ = [
class UserLoginContextMixin: class UserLoginContextMixin:
get_user_mfa_context: Callable get_user_mfa_context: Callable
request: HttpRequest request: HttpRequest
error_origin: str
def get_support_auth_methods(self): def get_support_auth_methods(self):
auth_methods = [ auth_methods = [
@ -134,19 +136,8 @@ class UserLoginContextMixin:
count += 1 count += 1
return count 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): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
origin_allowed, origin = self.origin_is_allowed()
context.update({ context.update({
'demo_mode': os.environ.get("DEMO_MODE"), 'demo_mode': os.environ.get("DEMO_MODE"),
'auth_methods': self.get_support_auth_methods(), 'auth_methods': self.get_support_auth_methods(),
@ -154,19 +145,19 @@ class UserLoginContextMixin:
'current_lang': self.get_current_lang(), 'current_lang': self.get_current_lang(),
'forgot_password_url': self.get_forgot_password_url(), 'forgot_password_url': self.get_forgot_password_url(),
'extra_fields_count': self.get_extra_fields_count(context), 'extra_fields_count': self.get_extra_fields_count(context),
'origin_is_allowed': origin_allowed, 'error_origin': self.error_origin,
'origin': origin,
**self.get_user_mfa_context(self.request.user) **self.get_user_mfa_context(self.request.user)
}) })
return context return context
@method_decorator(sensitive_post_parameters(), name='dispatch') @method_decorator(sensitive_post_parameters(), name='dispatch')
@method_decorator(csrf_protect, name='dispatch')
@method_decorator(never_cache, name='dispatch') @method_decorator(never_cache, name='dispatch')
@method_decorator(csrf_exempt, name='dispatch')
class UserLoginView(mixins.AuthMixin, UserLoginContextMixin, FormView): class UserLoginView(mixins.AuthMixin, UserLoginContextMixin, FormView):
redirect_field_name = 'next' redirect_field_name = 'next'
template_name = 'authentication/login.html' template_name = 'authentication/login.html'
error_origin = ''
def redirect_third_party_auth_if_need(self, request): def redirect_third_party_auth_if_need(self, request):
# show jumpserver login page if request http://{JUMP-SERVER}/?admin=1 # 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() request.session.set_test_cookie()
return super().get(request, *args, **kwargs) 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): def form_valid(self, form):
if not self.request.session.test_cookie_worked(): if not self.request.session.test_cookie_worked():
form.add_error(None, _("Login timeout, please try again.")) form.add_error(None, _("Login timeout, please try again."))
return self.form_invalid(form) 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 # https://docs.djangoproject.com/en/3.1/topics/http/sessions/#setting-test-cookies
self.request.session.delete_test_cookie() self.request.session.delete_test_cookie()