feat: add user login log (#126)

* feat: add user login log

* fix: checkstyle
This commit is contained in:
vran
2022-04-25 12:50:49 +08:00
committed by GitHub
parent d0a7a25a4d
commit 489182f7f5
7 changed files with 106 additions and 8 deletions

View File

@@ -1,8 +1,9 @@
package com.databasir.api.config.oauth2;
import com.databasir.api.config.security.DatabasirUserDetailService;
import com.databasir.core.domain.user.data.UserDetailResponse;
import com.databasir.core.domain.app.OpenAuthAppService;
import com.databasir.core.domain.log.service.OperationLogService;
import com.databasir.core.domain.user.data.UserDetailResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
@@ -33,6 +34,9 @@ public class DatabasirOauth2LoginFilter extends AbstractAuthenticationProcessing
@Autowired
private DatabasirUserDetailService databasirUserDetailService;
@Autowired
private OperationLogService operationLogService;
public DatabasirOauth2LoginFilter(AuthenticationManager authenticationManager,
OAuth2AuthenticationSuccessHandler auth2AuthenticationSuccessHandler,
AuthenticationFailureHandler authenticationFailureHandler) {
@@ -50,6 +54,7 @@ public class DatabasirOauth2LoginFilter extends AbstractAuthenticationProcessing
UserDetails details = databasirUserDetailService.loadUserByUsername(userDetailResponse.getUsername());
DatabasirOAuth2Authentication authentication = new DatabasirOAuth2Authentication(details);
if (!userDetailResponse.getEnabled()) {
operationLogService.saveLoginFailedLog(userDetailResponse.getUsername(), "用户被禁用");
throw new DisabledException("账号已禁用");
}
authentication.setAuthenticated(true);

View File

@@ -2,11 +2,12 @@ package com.databasir.api.config.oauth2;
import com.databasir.api.config.security.DatabasirUserDetails;
import com.databasir.common.JsonData;
import com.databasir.core.domain.login.data.LoginKeyResponse;
import com.databasir.core.domain.log.service.OperationLogService;
import com.databasir.core.domain.login.data.UserLoginResponse;
import com.databasir.core.domain.login.service.LoginService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.core.Authentication;
@@ -21,22 +22,30 @@ import java.nio.charset.StandardCharsets;
@Component
@RequiredArgsConstructor
@Slf4j
public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final LoginService loginService;
private final ObjectMapper objectMapper;
private final OperationLogService operationLogService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
DatabasirUserDetails details = (DatabasirUserDetails) authentication.getPrincipal();
LoginKeyResponse loginKey = loginService.generate(details.getUserPojo().getId());
loginService.generate(details.getUserPojo().getId());
UserLoginResponse data = loginService.getUserLoginData(details.getUserPojo().getId())
.orElseThrow(() -> new CredentialsExpiredException("请重新登陆"));
.orElseThrow(() -> {
operationLogService.saveLoginLog(details.getUserPojo(), false, null);
return new CredentialsExpiredException("请重新登陆");
});
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
objectMapper.writeValue(response.getWriter(), JsonData.ok(data));
operationLogService.saveLoginLog(details.getUserPojo(), true, null);
}
}

View File

@@ -2,8 +2,10 @@ package com.databasir.api.config.security;
import com.databasir.common.JsonData;
import com.databasir.core.domain.app.exception.DatabasirAuthenticationException;
import com.databasir.core.domain.log.service.OperationLogService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
@@ -20,37 +22,51 @@ import java.nio.charset.StandardCharsets;
@Component
@RequiredArgsConstructor
@Slf4j
public class DatabasirAuthenticationFailureHandler implements AuthenticationFailureHandler {
private final ObjectMapper objectMapper;
private final OperationLogService operationLogService;
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
String username = request.getParameter("username");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
if (exception instanceof BadCredentialsException) {
JsonData<Void> data = JsonData.error("-1", "用户名或密码错误");
saveLoginFailedLog(username, data.getErrMessage());
String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.OK.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
} else if (exception instanceof DisabledException) {
JsonData<Void> data = JsonData.error("-1", "用户已禁用");
saveLoginFailedLog(username, data.getErrMessage());
String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.OK.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
} else if (exception instanceof DatabasirAuthenticationException) {
DatabasirAuthenticationException bizException = (DatabasirAuthenticationException) exception;
JsonData<Void> data = JsonData.error(bizException.getErrCode(), bizException.getErrMessage());
saveLoginFailedLog(username, data.getErrMessage());
String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.OK.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
} else {
JsonData<Void> data = JsonData.error("-1", "未登录或未授权用户");
saveLoginFailedLog(username, data.getErrMessage());
String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
}
}
private void saveLoginFailedLog(String username, String message) {
if (username != null) {
operationLogService.saveLoginFailedLog(username, message);
}
}
}

View File

@@ -1,11 +1,12 @@
package com.databasir.api.config.security;
import com.databasir.common.JsonData;
import com.databasir.core.domain.login.data.LoginKeyResponse;
import com.databasir.core.domain.log.service.OperationLogService;
import com.databasir.core.domain.login.data.UserLoginResponse;
import com.databasir.core.domain.login.service.LoginService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.core.Authentication;
@@ -20,12 +21,15 @@ import java.nio.charset.StandardCharsets;
@Component
@RequiredArgsConstructor
@Slf4j
public class DatabasirAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final ObjectMapper objectMapper;
private final LoginService loginService;
private final OperationLogService operationLogService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
@@ -34,9 +38,13 @@ public class DatabasirAuthenticationSuccessHandler implements AuthenticationSucc
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
LoginKeyResponse loginKey = loginService.generate(user.getUserPojo().getId());
loginService.generate(user.getUserPojo().getId());
UserLoginResponse data = loginService.getUserLoginData(user.getUserPojo().getId())
.orElseThrow(() -> new CredentialsExpiredException("请重新登陆"));
.orElseThrow(() -> {
operationLogService.saveLoginLog(user.getUserPojo(), false, null);
return new CredentialsExpiredException("请重新登陆");
});
operationLogService.saveLoginLog(user.getUserPojo(), true, null);
objectMapper.writeValue(response.getWriter(), JsonData.ok(data));
}
}

View File

@@ -1,10 +1,12 @@
package com.databasir.api.config.security;
import com.databasir.core.domain.log.service.OperationLogService;
import com.databasir.dao.impl.UserDao;
import com.databasir.dao.impl.UserRoleDao;
import com.databasir.dao.tables.pojos.UserPojo;
import com.databasir.dao.tables.pojos.UserRolePojo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@@ -15,16 +17,22 @@ import java.util.List;
@Service
@RequiredArgsConstructor
@Slf4j
public class DatabasirUserDetailService implements UserDetailsService {
private final UserDao userDao;
private final UserRoleDao userRoleDao;
private final OperationLogService operationLogService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserPojo user = userDao.selectByEmailOrUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("用户名或密码错误"));
.orElseThrow(() -> {
operationLogService.saveLoginFailedLog(username, "用户名不存在");
return new UsernameNotFoundException("用户名或密码错误");
});
List<UserRolePojo> roles = userRoleDao.selectByUserIds(Collections.singletonList(user.getId()));
return new DatabasirUserDetails(user, roles);
}