📄 登录异常个性化处理
内部资料,请扫码登录
pigcloud
# v4.6 版本及其以上版本
4.6 版本
在 4.6 版本中 pigx 将默认的 AuthenticationException
处理器修改成如下
@RequiredArgsConstructor
public class ResourceAuthExceptionEntryPoint implements AuthenticationEntryPoint {
private final ObjectMapper objectMapper;
private final MessageSource messageSource;
@Override
@SneakyThrows
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) {
response.setCharacterEncoding(CommonConstants.UTF8);
response.setContentType(ContentType.JSON.getValue());
R<String> result = new R<>();
result.setCode(CommonConstants.FAIL);
response.setStatus(HttpStatus.UNAUTHORIZED.value());
if (authException != null) {
result.setMsg("error");
result.setData(authException.getMessage());
}
// 针对令牌过期返回特殊的 424
if (authException instanceof InvalidBearerTokenException
|| authException instanceof InsufficientAuthenticationException) {
response.setStatus(HttpStatus.FAILED_DEPENDENCY.value());
result.setMsg(this.messageSource.getMessage("OAuth2ResourceOwnerBaseAuthenticationProvider.tokenExpired",
null, LocaleContextHolder.getLocale()));
}
PrintWriter printWriter = response.getWriter();
printWriter.append(objectMapper.writeValueAsString(result));
}
}
会处理所有 AuthenticationException
的子类进行错误返回,可根据自己对不同业务单独进行判断处理
# 低版本修改
# 原理篇
# 目标
如上图, pigx 在默认登录失败的情况下,只会返回给前端 用户名或密码不正确 的业务提示。 在实际的业务过程中,需要基于项目需要给客户端更多的明确信息提示。
# 代码扩展
- 如果你已经看了 登录 token 生成 (opens new window) 章节的文档,那么肯定就会知道 spring security 最终是通过的 UserDetailsService.loadUserByUsername 来加载项目的用户体系至 spring security oauth 完成认证授权。
- 如上所述,系统目前只抛出 用户名或密码不正确
- 此处可以根据 feign 调用 upms 查询结果进行更细化处理,扔出新的异常
PigxAuth2Exception
private UserDetails getUserDetails(R<UserInfo> result) {
//此处根据feign 查询结果进行个性化判断 扔出PigxAuth2Exception
if ("1".equals(result.getData().getSysUser().getLockFlag())) {
throw new PigxAuth2Exception("账号已被锁定");
}
}
# 原理解析
- 此处扔出的异常都会被
PigxWebResponseExceptionTranslator.translate
集中格式化处理
最终调用 PigxAuth2ExceptionSerializer 序列化规则输出给客户端
public class PigxAuth2ExceptionSerializer extends StdSerializer<PigxAuth2Exception> {
public PigxAuth2ExceptionSerializer() {
super(PigxAuth2Exception.class);
}
@Override
@SneakyThrows
public void serialize(PigxAuth2Exception value, JsonGenerator gen, SerializerProvider provider) {
gen.writeStartObject();
gen.writeObjectField("code", CommonConstants.FAIL);
gen.writeStringField("msg", value.getMessage());
gen.writeStringField("data", value.getErrorCode());
gen.writeEndObject();
}
}