mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-05-03 09:43:55 +00:00
fix: many login logs are record when user login once
This commit is contained in:
@@ -3,6 +3,8 @@ from django.contrib.auth.backends import ModelBackend
|
||||
|
||||
from common.utils import get_logger
|
||||
from users.models import User
|
||||
from authentication.signals import backend_auth_failed
|
||||
from authentication.errors import reason_choices, reason_user_invalid
|
||||
|
||||
UserModel = get_user_model()
|
||||
logger = get_logger(__file__)
|
||||
@@ -65,3 +67,14 @@ class JMSBaseAuthBackend:
|
||||
class JMSModelBackend(JMSBaseAuthBackend, ModelBackend):
|
||||
def user_can_authenticate(self, user):
|
||||
return True
|
||||
|
||||
|
||||
class RedirectAuthBackend(JMSBaseAuthBackend):
|
||||
backend = None
|
||||
|
||||
def send_backend_auth_failed_signal(self, request, username=None, reason=None):
|
||||
default_reason = reason_choices.get(reason_user_invalid, reason)
|
||||
backend_auth_failed.send(
|
||||
sender=self.__class__, username=username, request=request,
|
||||
reason=default_reason, backend=self.backend
|
||||
)
|
||||
|
||||
@@ -5,13 +5,15 @@ from django.conf import settings
|
||||
from django_cas_ng.backends import CASBackend as _CASBackend
|
||||
|
||||
from common.utils import get_logger
|
||||
from ..base import JMSBaseAuthBackend
|
||||
from ..base import RedirectAuthBackend
|
||||
|
||||
__all__ = ['CASBackend']
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class CASBackend(JMSBaseAuthBackend, _CASBackend):
|
||||
class CASBackend(RedirectAuthBackend, _CASBackend):
|
||||
backend = settings.AUTH_BACKEND_CAS
|
||||
|
||||
@staticmethod
|
||||
def is_enabled():
|
||||
return settings.AUTH_CAS
|
||||
@@ -19,4 +21,7 @@ class CASBackend(JMSBaseAuthBackend, _CASBackend):
|
||||
def authenticate(self, request, ticket, service):
|
||||
# 这里做个hack ,让父类始终走CAS_CREATE_USER=True的逻辑,然后调用 authentication/mixins.py 中的 custom_get_or_create 方法
|
||||
settings.CAS_CREATE_USER = True
|
||||
return super().authenticate(request, ticket, service)
|
||||
user = super().authenticate(request, ticket, service)
|
||||
if user is None:
|
||||
self.send_backend_auth_failed_signal(request=request)
|
||||
return user
|
||||
|
||||
@@ -3,7 +3,6 @@ from django.contrib.auth import get_user_model
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from authentication.signals import user_auth_failed, user_auth_success
|
||||
from common.utils import get_logger
|
||||
from .base import JMSBaseAuthBackend
|
||||
|
||||
@@ -48,16 +47,7 @@ class CustomAuthBackend(JMSBaseAuthBackend):
|
||||
|
||||
if self.user_can_authenticate(user):
|
||||
logger.info(f'Custom authenticate success: {user.username}')
|
||||
user_auth_success.send(
|
||||
sender=self.__class__, request=request, user=user,
|
||||
backend=settings.AUTH_BACKEND_CUSTOM
|
||||
)
|
||||
return user
|
||||
else:
|
||||
logger.info(f'Custom authenticate failed: {user.username}')
|
||||
user_auth_failed.send(
|
||||
sender=self.__class__, request=request, username=user.username,
|
||||
reason=_('User invalid, disabled or expired'),
|
||||
backend=settings.AUTH_BACKEND_CUSTOM
|
||||
)
|
||||
return None
|
||||
|
||||
@@ -12,13 +12,12 @@ from django.urls import reverse
|
||||
from common.utils import get_logger
|
||||
from users.utils import construct_user_email
|
||||
from authentication.utils import build_absolute_uri
|
||||
from authentication.signals import user_auth_failed, user_auth_success
|
||||
from common.exceptions import JMSException
|
||||
|
||||
from .signals import (
|
||||
oauth2_create_or_update_user
|
||||
)
|
||||
from ..base import JMSBaseAuthBackend
|
||||
from ..base import RedirectAuthBackend
|
||||
|
||||
|
||||
__all__ = ['OAuth2Backend']
|
||||
@@ -26,7 +25,9 @@ __all__ = ['OAuth2Backend']
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class OAuth2Backend(JMSBaseAuthBackend):
|
||||
class OAuth2Backend(RedirectAuthBackend):
|
||||
backend = settings.AUTH_BACKEND_OAUTH2
|
||||
|
||||
@staticmethod
|
||||
def is_enabled():
|
||||
return settings.AUTH_OAUTH2
|
||||
@@ -144,18 +145,9 @@ class OAuth2Backend(JMSBaseAuthBackend):
|
||||
|
||||
if self.user_can_authenticate(user):
|
||||
logger.debug(log_prompt.format('OAuth2 user login success'))
|
||||
logger.debug(log_prompt.format('Send signal => oauth2 user login success'))
|
||||
user_auth_success.send(
|
||||
sender=self.__class__, request=request, user=user,
|
||||
backend=settings.AUTH_BACKEND_OAUTH2
|
||||
)
|
||||
return user
|
||||
else:
|
||||
logger.debug(log_prompt.format('OAuth2 user login failed'))
|
||||
logger.debug(log_prompt.format('Send signal => oauth2 user login failed'))
|
||||
user_auth_failed.send(
|
||||
sender=self.__class__, request=request, username=user.username,
|
||||
reason=_('User invalid, disabled or expired'),
|
||||
backend=settings.AUTH_BACKEND_OAUTH2
|
||||
)
|
||||
self.send_backend_auth_failed_signal(request=request, username=user.username)
|
||||
return None
|
||||
|
||||
@@ -16,7 +16,6 @@ from django.contrib.auth.backends import ModelBackend
|
||||
from django.db import transaction
|
||||
from django.urls import reverse
|
||||
|
||||
from authentication.signals import user_auth_success, user_auth_failed
|
||||
from authentication.utils import build_absolute_uri_for_oidc
|
||||
from common.utils import get_logger
|
||||
from users.utils import construct_user_email
|
||||
@@ -25,7 +24,7 @@ from .signals import (
|
||||
openid_create_or_update_user
|
||||
)
|
||||
from .utils import validate_and_return_id_token
|
||||
from ..base import JMSBaseAuthBackend
|
||||
from ..base import RedirectAuthBackend, JMSBaseAuthBackend
|
||||
|
||||
logger = get_logger(__file__)
|
||||
|
||||
@@ -66,14 +65,14 @@ class UserMixin:
|
||||
return user, created
|
||||
|
||||
|
||||
class OIDCBaseBackend(UserMixin, JMSBaseAuthBackend, ModelBackend):
|
||||
class OIDCBaseBackend(UserMixin, ModelBackend):
|
||||
|
||||
@staticmethod
|
||||
def is_enabled():
|
||||
return settings.AUTH_OPENID
|
||||
|
||||
|
||||
class OIDCAuthCodeBackend(OIDCBaseBackend):
|
||||
class OIDCAuthCodeBackend(RedirectAuthBackend, OIDCBaseBackend):
|
||||
""" Allows to authenticate users using an OpenID Connect Provider (OP).
|
||||
|
||||
This authentication backend is able to authenticate users in the case of the OpenID Connect
|
||||
@@ -84,6 +83,8 @@ class OIDCAuthCodeBackend(OIDCBaseBackend):
|
||||
|
||||
"""
|
||||
|
||||
backend = settings.AUTH_BACKEND_OIDC_CODE
|
||||
|
||||
@ssl_verification
|
||||
def authenticate(self, request, nonce=None, code_verifier=None):
|
||||
""" Authenticates users in case of the OpenID Connect Authorization code flow. """
|
||||
@@ -212,23 +213,15 @@ class OIDCAuthCodeBackend(OIDCBaseBackend):
|
||||
|
||||
if self.user_can_authenticate(user):
|
||||
logger.debug(log_prompt.format('OpenID user login success'))
|
||||
logger.debug(log_prompt.format('Send signal => openid user login success'))
|
||||
user_auth_success.send(
|
||||
sender=self.__class__, request=request, user=user,
|
||||
backend=settings.AUTH_BACKEND_OIDC_CODE
|
||||
)
|
||||
return user
|
||||
else:
|
||||
logger.debug(log_prompt.format('OpenID user login failed'))
|
||||
logger.debug(log_prompt.format('Send signal => openid user login failed'))
|
||||
user_auth_failed.send(
|
||||
sender=self.__class__, request=request, username=user.username,
|
||||
reason="User is invalid", backend=settings.AUTH_BACKEND_OIDC_CODE
|
||||
)
|
||||
self.send_backend_auth_failed_signal(request=request, username=user.username)
|
||||
return None
|
||||
|
||||
|
||||
class OIDCAuthPasswordBackend(OIDCBaseBackend):
|
||||
class OIDCAuthPasswordBackend(JMSBaseAuthBackend, OIDCBaseBackend):
|
||||
|
||||
@ssl_verification
|
||||
def authenticate(self, request, username=None, password=None):
|
||||
@@ -274,11 +267,6 @@ class OIDCAuthPasswordBackend(OIDCBaseBackend):
|
||||
error = "Json token response error, token response " \
|
||||
"content is: {}, error is: {}".format(token_response.content, str(e))
|
||||
logger.debug(log_prompt.format(error))
|
||||
logger.debug(log_prompt.format('Send signal => openid user login failed'))
|
||||
user_auth_failed.send(
|
||||
sender=self.__class__, request=request, username=username, reason=error,
|
||||
backend=settings.AUTH_BACKEND_OIDC_PASSWORD
|
||||
)
|
||||
return
|
||||
|
||||
# Retrieves the access token
|
||||
@@ -303,11 +291,6 @@ class OIDCAuthPasswordBackend(OIDCBaseBackend):
|
||||
error = "Json claims response error, claims response " \
|
||||
"content is: {}, error is: {}".format(claims_response.content, str(e))
|
||||
logger.debug(log_prompt.format(error))
|
||||
logger.debug(log_prompt.format('Send signal => openid user login failed'))
|
||||
user_auth_failed.send(
|
||||
sender=self.__class__, request=request, username=username, reason=error,
|
||||
backend=settings.AUTH_BACKEND_OIDC_PASSWORD
|
||||
)
|
||||
return
|
||||
|
||||
logger.debug(log_prompt.format('Get or create user from claims'))
|
||||
@@ -317,17 +300,7 @@ class OIDCAuthPasswordBackend(OIDCBaseBackend):
|
||||
|
||||
if self.user_can_authenticate(user):
|
||||
logger.debug(log_prompt.format('OpenID user login success'))
|
||||
logger.debug(log_prompt.format('Send signal => openid user login success'))
|
||||
user_auth_success.send(
|
||||
sender=self.__class__, request=request, user=user,
|
||||
backend=settings.AUTH_BACKEND_OIDC_PASSWORD
|
||||
)
|
||||
return user
|
||||
else:
|
||||
logger.debug(log_prompt.format('OpenID user login failed'))
|
||||
logger.debug(log_prompt.format('Send signal => openid user login failed'))
|
||||
user_auth_failed.send(
|
||||
sender=self.__class__, request=request, username=username, reason="User is invalid",
|
||||
backend=settings.AUTH_BACKEND_OIDC_PASSWORD
|
||||
)
|
||||
return None
|
||||
|
||||
@@ -5,19 +5,19 @@ from django.conf import settings
|
||||
from django.db import transaction
|
||||
|
||||
from common.utils import get_logger
|
||||
from authentication.errors import reason_choices, reason_user_invalid
|
||||
from .signals import (
|
||||
saml2_create_or_update_user
|
||||
)
|
||||
from authentication.signals import user_auth_failed, user_auth_success
|
||||
from ..base import JMSBaseAuthBackend
|
||||
from ..base import RedirectAuthBackend
|
||||
|
||||
__all__ = ['SAML2Backend']
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class SAML2Backend(JMSBaseAuthBackend):
|
||||
class SAML2Backend(RedirectAuthBackend):
|
||||
backend = settings.AUTH_BACKEND_SAML2
|
||||
|
||||
@staticmethod
|
||||
def is_enabled():
|
||||
return settings.AUTH_SAML2
|
||||
@@ -59,16 +59,8 @@ class SAML2Backend(JMSBaseAuthBackend):
|
||||
|
||||
if self.user_can_authenticate(user):
|
||||
logger.debug(log_prompt.format('SAML2 user login success'))
|
||||
user_auth_success.send(
|
||||
sender=self.__class__, request=request, user=user, created=created,
|
||||
backend=settings.AUTH_BACKEND_SAML2
|
||||
)
|
||||
return user
|
||||
else:
|
||||
logger.debug(log_prompt.format('SAML2 user login failed'))
|
||||
user_auth_failed.send(
|
||||
sender=self.__class__, request=request, username=username,
|
||||
reason=reason_choices.get(reason_user_invalid),
|
||||
backend=settings.AUTH_BACKEND_SAML2
|
||||
)
|
||||
self.send_backend_auth_failed_signal(request=request, username=user.username)
|
||||
return None
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.utils.translation import gettext as _
|
||||
|
||||
from apps.authentication import mixins
|
||||
from audits.signal_handlers import send_login_info_to_reviewers
|
||||
from authentication.signals import post_auth_failed
|
||||
from authentication.signals import post_auth_failed, post_auth_success
|
||||
from common.utils import gen_key_pair, gen_gm_key_pair
|
||||
from common.utils import get_request_ip
|
||||
|
||||
@@ -101,6 +101,9 @@ class ThirdPartyLoginMiddleware(mixins.AuthMixin):
|
||||
response = render(request, 'authentication/auth_fail_flash_message_standalone.html', context)
|
||||
else:
|
||||
if not self.request.session.get('auth_confirm_required'):
|
||||
post_auth_success.send(
|
||||
sender=self.__class__, user=request.user, request=self.request
|
||||
)
|
||||
return response
|
||||
guard_url = reverse('authentication:login-guard')
|
||||
args = request.META.get('QUERY_STRING', '')
|
||||
|
||||
@@ -177,6 +177,9 @@ def authenticate(request=None, **credentials):
|
||||
if user is None:
|
||||
continue
|
||||
|
||||
if request:
|
||||
request.session['auth_backend'] = backend_path
|
||||
|
||||
if not user.is_valid:
|
||||
temp_user = user
|
||||
temp_user.backend = backend_path
|
||||
|
||||
@@ -7,7 +7,7 @@ from django_cas_ng.signals import cas_user_authenticated
|
||||
from apps.jumpserver.settings.auth import AUTHENTICATION_BACKENDS_THIRD_PARTY
|
||||
from audits.models import UserSession
|
||||
from common.sessions.cache import user_session_manager
|
||||
from .signals import post_auth_success, post_auth_failed, user_auth_failed, user_auth_success
|
||||
from .signals import post_auth_failed, backend_auth_failed
|
||||
|
||||
from .backends.oauth2_provider.signal_handlers import *
|
||||
|
||||
@@ -43,19 +43,7 @@ def on_user_auth_login_success(sender, user, request, **kwargs):
|
||||
user.lang = lang
|
||||
|
||||
|
||||
@receiver(cas_user_authenticated)
|
||||
def on_cas_user_login_success(sender, request, user, **kwargs):
|
||||
request.session['auth_backend'] = settings.AUTH_BACKEND_CAS
|
||||
post_auth_success.send(sender, user=user, request=request)
|
||||
|
||||
|
||||
@receiver(user_auth_success)
|
||||
def on_user_login_success(sender, request, user, backend, create=False, **kwargs):
|
||||
request.session['auth_backend'] = backend
|
||||
post_auth_success.send(sender, user=user, request=request)
|
||||
|
||||
|
||||
@receiver(user_auth_failed)
|
||||
@receiver(backend_auth_failed)
|
||||
def on_user_login_failed(sender, username, request, reason, backend, **kwargs):
|
||||
request.session['auth_backend'] = backend
|
||||
post_auth_failed.send(sender, username=username, request=request, reason=reason)
|
||||
|
||||
@@ -3,5 +3,4 @@ from django.dispatch import Signal
|
||||
post_auth_success = Signal()
|
||||
post_auth_failed = Signal()
|
||||
|
||||
user_auth_success = Signal()
|
||||
user_auth_failed = Signal()
|
||||
backend_auth_failed = Signal()
|
||||
|
||||
Reference in New Issue
Block a user