perf(auth): 授权token形式登录,支持记录登录日志

pull/6259/head
ibuler 2021-06-10 18:02:55 +08:00 committed by 老广
parent 7dddf0c3c2
commit db99ab80db
6 changed files with 40 additions and 14 deletions

View File

@ -94,8 +94,14 @@ class CommandExecutionViewSet(ListModelMixin, OrgGenericViewSet):
date_range_filter_fields = [
('date_start', ('date_from', 'date_to'))
]
filterset_fields = ['user__name', 'command', 'run_as__name', 'is_finished']
search_fields = ['command', 'user__name', 'run_as__name']
filterset_fields = [
'user__name', 'user__username', 'command',
'run_as__name', 'run_as__username', 'is_finished'
]
search_fields = [
'command', 'user__name', 'user__username',
'run_as__name', 'run_as__username',
]
ordering = ['-date_created']
def get_queryset(self):

View File

@ -82,7 +82,7 @@ class CommandExecutionSerializer(serializers.ModelSerializer):
model = CommandExecution
fields_mini = ['id']
fields_small = fields_mini + [
'run_as', 'command', 'user', 'is_finished',
'run_as', 'command', 'is_finished', 'user',
'date_start', 'result', 'is_success', 'org_id'
]
fields = fields_small + ['hosts', 'hosts_display', 'run_as_display', 'user_display']

View File

@ -57,6 +57,7 @@ class AuthBackendLabelMapping(LazyObject):
backend_label_mapping[settings.AUTH_BACKEND_PUBKEY] = _('SSH Key')
backend_label_mapping[settings.AUTH_BACKEND_MODEL] = _('Password')
backend_label_mapping[settings.AUTH_BACKEND_SSO] = _('SSO')
backend_label_mapping[settings.AUTH_BACKEND_AUTH_TOKEN] = _('Auth Token')
backend_label_mapping[settings.AUTH_BACKEND_WECOM] = _('WeCom')
backend_label_mapping[settings.AUTH_BACKEND_DINGTALK] = _('DingTalk')
return backend_label_mapping
@ -156,12 +157,13 @@ def get_login_backend(request):
return backend_label
def generate_data(username, request):
def generate_data(username, request, login_type=None):
user_agent = request.META.get('HTTP_USER_AGENT', '')
login_ip = get_request_ip(request) or '0.0.0.0'
if isinstance(request, Request):
if login_type is None and isinstance(request, Request):
login_type = request.META.get('HTTP_X_JMS_LOGIN_TYPE', 'U')
else:
if login_type is None:
login_type = 'W'
data = {
@ -176,9 +178,9 @@ def generate_data(username, request):
@receiver(post_auth_success)
def on_user_auth_success(sender, user, request, **kwargs):
def on_user_auth_success(sender, user, request, login_type=None, **kwargs):
logger.debug('User login success: {}'.format(user.username))
data = generate_data(user.username, request)
data = generate_data(user.username, request, login_type=login_type)
data.update({'mfa': int(user.mfa_enabled), 'status': True})
write_login_log(**data)

View File

@ -6,12 +6,14 @@ from django.conf import settings
from django.core.cache import cache
from django.shortcuts import get_object_or_404
from django.http import HttpResponse
from django.utils.translation import ugettext as _
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
from rest_framework import serializers
from authentication.signals import post_auth_failed, post_auth_success
from common.utils import get_logger, random_string
from common.drf.api import SerializerMixin2
from common.permissions import IsSuperUserOrAppUser, IsValidUser, IsSuperUser
@ -51,10 +53,6 @@ class UserConnectionTokenViewSet(RootOrgViewMixin, SerializerMixin2, GenericView
return True
def create_token(self, user, asset, application, system_user, ttl=5*60):
if not settings.CONNECTION_TOKEN_ENABLED:
raise PermissionDenied('Connection token disabled')
if not user:
user = self.request.user
if not self.request.user.is_superuser and user != self.request.user:
raise PermissionDenied('Only super user can create user token')
self.check_resource_permission(user, asset, application, system_user)
@ -238,7 +236,14 @@ class UserConnectionTokenViewSet(RootOrgViewMixin, SerializerMixin2, GenericView
@action(methods=['POST'], detail=False, permission_classes=[IsSuperUserOrAppUser], url_path='secret-info/detail')
def get_secret_detail(self, request, *args, **kwargs):
token = request.data.get('token', '')
value, user, system_user, asset, app = self.valid_token(token)
try:
value, user, system_user, asset, app = self.valid_token(token)
except serializers.ValidationError as e:
post_auth_failed.send(
sender=self.__class__, username='', request=self.request,
reason=_('Invalid token')
)
raise e
data = dict(user=user, system_user=system_user)
if asset:
@ -252,6 +257,9 @@ class UserConnectionTokenViewSet(RootOrgViewMixin, SerializerMixin2, GenericView
data['type'] = 'application'
data.update(app_detail)
self.request.session['auth_backend'] = settings.AUTH_BACKEND_AUTH_TOKEN
post_auth_success.send(sender=self.__class__, user=user, request=self.request, login_type='T')
serializer = self.get_serializer(data)
return Response(data=serializer.data, status=200)

View File

@ -228,3 +228,11 @@ class DingTalkAuthentication(ModelBackend):
def authenticate(self, request, **kwargs):
pass
class AuthorizationTokenAuthentication(ModelBackend):
"""
什么也不做呀😺
"""
def authenticate(self, request, **kwargs):
pass

View File

@ -130,10 +130,12 @@ AUTH_BACKEND_CAS = 'authentication.backends.cas.CASBackend'
AUTH_BACKEND_SSO = 'authentication.backends.api.SSOAuthentication'
AUTH_BACKEND_WECOM = 'authentication.backends.api.WeComAuthentication'
AUTH_BACKEND_DINGTALK = 'authentication.backends.api.DingTalkAuthentication'
AUTH_BACKEND_AUTH_TOKEN = 'authentication.backends.api.AuthorizationTokenAuthentication'
AUTHENTICATION_BACKENDS = [
AUTH_BACKEND_MODEL, AUTH_BACKEND_PUBKEY, AUTH_BACKEND_WECOM, AUTH_BACKEND_DINGTALK
AUTH_BACKEND_MODEL, AUTH_BACKEND_PUBKEY, AUTH_BACKEND_WECOM,
AUTH_BACKEND_DINGTALK, AUTH_BACKEND_AUTH_TOKEN
]
if AUTH_CAS: