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