mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 12:39:05 +08:00
♻️ 优化异常抛出逻辑,方便二次扩展
This commit is contained in:
1 parent
134eb660aa
commit
34b9ec490d
1 file changed
+95
-92
+95
-92
@@ -23,15 +23,12 @@ import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.KeyStrResolver;
|
||||
import com.pig4cloud.pigx.common.core.util.MsgUtils;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.core.util.WebUtils;
|
||||
import com.pig4cloud.pigx.common.data.resolver.ParamResolver;
|
||||
import com.pig4cloud.pigx.common.log.event.SysLogEvent;
|
||||
import com.pig4cloud.pigx.common.log.util.LogTypeEnum;
|
||||
import com.pig4cloud.pigx.common.log.util.SysLogUtils;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -48,6 +45,8 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -60,110 +59,114 @@ import java.util.concurrent.TimeUnit;
|
||||
@RequiredArgsConstructor
|
||||
public class PigxAuthenticationFailureEventHandler implements AuthenticationFailureHandler {
|
||||
|
||||
private static final MappingJackson2HttpMessageConverter errorHttpResponseConverter = new MappingJackson2HttpMessageConverter();
|
||||
private static final MappingJackson2HttpMessageConverter errorHttpResponseConverter = new MappingJackson2HttpMessageConverter();
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
private final ApplicationEventPublisher publisher;
|
||||
private final ApplicationEventPublisher publisher;
|
||||
|
||||
private final KeyStrResolver tenantKeyStrResolver;
|
||||
private final KeyStrResolver tenantKeyStrResolver;
|
||||
|
||||
private final RemoteUserService userService;
|
||||
private final RemoteUserService userService;
|
||||
|
||||
/**
|
||||
* Called when an authentication attempt fails.
|
||||
* @param request the request during which the authentication attempt occurred.
|
||||
* @param response the response.
|
||||
* @param exception the exception which was thrown to reject the authentication
|
||||
* request.
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) {
|
||||
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
|
||||
log.info("登录失败,异常:{}", exception.getLocalizedMessage());
|
||||
/**
|
||||
* Called when an authentication attempt fails.
|
||||
*
|
||||
* @param request the request during which the authentication attempt occurred.
|
||||
* @param response the response.
|
||||
* @param exception the exception which was thrown to reject the authentication
|
||||
* request.
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) {
|
||||
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
|
||||
log.info("登录失败,异常:{}", exception.getLocalizedMessage());
|
||||
|
||||
// 密码模式记录错误信息
|
||||
if (OAuth2ParameterNames.PASSWORD.equals(grantType)) {
|
||||
String username = request.getParameter(OAuth2ParameterNames.USERNAME);
|
||||
// 密码模式记录错误信息
|
||||
if (OAuth2ParameterNames.PASSWORD.equals(grantType)) {
|
||||
String username = request.getParameter(OAuth2ParameterNames.USERNAME);
|
||||
|
||||
// 密码错误记录错误次数 (TOC用户不记录)
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
if (exception instanceof OAuth2AuthenticationException
|
||||
&& !SecurityConstants.HEADER_TOC_YES.equals(header)) {
|
||||
recordLoginFailureTimes(username);
|
||||
}
|
||||
// 密码错误记录错误次数 (TOC用户不记录)
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
if (exception instanceof OAuth2AuthenticationException
|
||||
&& !SecurityConstants.HEADER_TOC_YES.equals(header)) {
|
||||
recordLoginFailureTimes(username);
|
||||
}
|
||||
|
||||
// 记录登录失败错误信息
|
||||
sendFailureEventLog(request, exception, username);
|
||||
}
|
||||
// 记录登录失败错误信息
|
||||
sendFailureEventLog(request, exception, username);
|
||||
}
|
||||
|
||||
// 写出错误信息
|
||||
sendErrorResponse(request, response, exception);
|
||||
}
|
||||
// 写出错误信息
|
||||
sendErrorResponse(request, response, exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录失败日志
|
||||
* @param request HttpServletRequest
|
||||
* @param exception 错误日志
|
||||
* @param username 用户名
|
||||
*/
|
||||
private void sendFailureEventLog(HttpServletRequest request, AuthenticationException exception, String username) {
|
||||
SysLogDTO logVo = SysLogUtils.getSysLog();
|
||||
logVo.setTitle("登录失败");
|
||||
logVo.setLogType(LogTypeEnum.ERROR.getType());
|
||||
logVo.setException(exception.getLocalizedMessage());
|
||||
// 发送异步日志事件
|
||||
String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
|
||||
if (StrUtil.isNotBlank(startTimeStr)) {
|
||||
Long startTime = Long.parseLong(startTimeStr);
|
||||
Long endTime = System.currentTimeMillis();
|
||||
logVo.setTime(endTime - startTime);
|
||||
}
|
||||
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
String clientId = WebUtils.extractClientId(header).orElse(null);
|
||||
logVo.setServiceId(clientId);
|
||||
logVo.setCreateBy(username);
|
||||
logVo.setTenantId(Long.parseLong(tenantKeyStrResolver.key()));
|
||||
publisher.publishEvent(new SysLogEvent(logVo));
|
||||
}
|
||||
/**
|
||||
* 记录失败日志
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @param exception 错误日志
|
||||
* @param username 用户名
|
||||
*/
|
||||
private void sendFailureEventLog(HttpServletRequest request, AuthenticationException exception, String username) {
|
||||
SysLogDTO logVo = SysLogUtils.getSysLog();
|
||||
logVo.setTitle("登录失败");
|
||||
logVo.setLogType(LogTypeEnum.ERROR.getType());
|
||||
logVo.setException(exception.getLocalizedMessage());
|
||||
// 发送异步日志事件
|
||||
String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
|
||||
if (StrUtil.isNotBlank(startTimeStr)) {
|
||||
Long startTime = Long.parseLong(startTimeStr);
|
||||
Long endTime = System.currentTimeMillis();
|
||||
logVo.setTime(endTime - startTime);
|
||||
}
|
||||
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
String clientId = WebUtils.extractClientId(header).orElse(null);
|
||||
logVo.setServiceId(clientId);
|
||||
logVo.setCreateBy(username);
|
||||
logVo.setTenantId(Long.parseLong(tenantKeyStrResolver.key()));
|
||||
publisher.publishEvent(new SysLogEvent(logVo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录失败此处,如果操作阈值 调用接口锁定用户
|
||||
* @param username username
|
||||
*/
|
||||
private void recordLoginFailureTimes(String username) {
|
||||
String key = String.format("%s:%s:%s", tenantKeyStrResolver.key(), CacheConstants.LOGIN_ERROR_TIMES, username);
|
||||
Long deltaTimes = ParamResolver.getLong("LOGIN_ERROR_TIMES", 5L);
|
||||
Long times = redisTemplate.opsForValue().increment(key);
|
||||
/**
|
||||
* 记录登录失败此处,如果操作阈值 调用接口锁定用户
|
||||
*
|
||||
* @param username username
|
||||
*/
|
||||
private void recordLoginFailureTimes(String username) {
|
||||
String key = String.format("%s:%s:%s", tenantKeyStrResolver.key(), CacheConstants.LOGIN_ERROR_TIMES, username);
|
||||
Long deltaTimes = ParamResolver.getLong("LOGIN_ERROR_TIMES", 5L);
|
||||
Long times = redisTemplate.opsForValue().increment(key);
|
||||
|
||||
// 自动过期时间
|
||||
Long deltaTime = ParamResolver.getLong("DELTA_TIME", 1L);
|
||||
redisTemplate.expire(key, deltaTime, TimeUnit.HOURS);
|
||||
// 自动过期时间
|
||||
Long deltaTime = ParamResolver.getLong("DELTA_TIME", 1L);
|
||||
redisTemplate.expire(key, deltaTime, TimeUnit.HOURS);
|
||||
|
||||
if (deltaTimes <= times) {
|
||||
userService.lockUser(username, SecurityConstants.FROM_IN);
|
||||
}
|
||||
}
|
||||
if (deltaTimes <= times) {
|
||||
userService.lockUser(username, SecurityConstants.FROM_IN);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
|
||||
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
String errorMessage;
|
||||
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
|
||||
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
String errorMessage;
|
||||
|
||||
if (exception instanceof OAuth2AuthenticationException) {
|
||||
OAuth2AuthenticationException authorizationException = (OAuth2AuthenticationException) exception;
|
||||
errorMessage = StrUtil.isBlank(authorizationException.getError().getDescription())
|
||||
? authorizationException.getError().getErrorCode()
|
||||
: authorizationException.getError().getDescription();
|
||||
}
|
||||
else {
|
||||
errorMessage = exception.getLocalizedMessage();
|
||||
}
|
||||
if (exception instanceof OAuth2AuthenticationException) {
|
||||
OAuth2AuthenticationException authorizationException = (OAuth2AuthenticationException) exception;
|
||||
errorMessage = StrUtil.isBlank(authorizationException.getError().getDescription())
|
||||
? authorizationException.getError().getErrorCode()
|
||||
: authorizationException.getError().getDescription();
|
||||
|
||||
this.errorHttpResponseConverter.write(R.failed(errorMessage), MediaType.APPLICATION_JSON, httpResponse);
|
||||
}
|
||||
this.errorHttpResponseConverter.write(R.failed(authorizationException.getError().getErrorCode(), errorMessage), MediaType.APPLICATION_JSON, httpResponse);
|
||||
|
||||
} else {
|
||||
errorMessage = exception.getLocalizedMessage();
|
||||
this.errorHttpResponseConverter.write(R.failed(errorMessage), MediaType.APPLICATION_JSON, httpResponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user