spring security中,自定义异常无法正常返回

staton_ 2021-05-10 11:41:02

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if ((request.getContentType() == null && request.getContentLength() > 0) || (request.getContentType() != null && !request.getContentType().contains(Constants.REQUEST_HEADERS_CONTENT_TYPE))) {
filterChain.doFilter(request, response);
return;
}

MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(request);
MultiReadHttpServletResponse wrappedResponse = new MultiReadHttpServletResponse(response);
StopWatch stopWatch = new StopWatch();
try {
stopWatch.start();
// 记录请求的消息体
logRequestBody(wrappedRequest);

// 前后端分离情况下,前端登录后将token储存在cookie中,每次访问接口时通过token去拿用户权限
String jwtToken = wrappedRequest.getHeader(Constants.REQUEST_HEADER);
log.debug("后台检查令牌:{}", jwtToken);
if (StringUtils.isNotBlank(jwtToken)) {
// 检查token
// JWT相关start ===========================================
// 获取jwt中的信息
Claims claims = Jwts.parser().setSigningKey(Constants.SALT).parseClaimsJws(jwtToken.replace("Bearer", "")).getBody();
// 获取当前登录用户名
System.out.println("获取当前登录用户名: " + claims.getSubject());
// TODO 如需使用jwt特性在此做处理~
// JWT相关end ===========================================

SecurityUser securityUser = userDetailsService.getUserByToken(jwtToken);
if (securityUser == null || securityUser.getCurrentUserInfo() == null) {
throw new MyException("TOKEN已过期,请重新登录!");
}
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities());
// 全局注入角色权限信息和登录用户基本信息
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(wrappedRequest, wrappedResponse);
}finally {
stopWatch.stop();
long usedTimes = stopWatch.getTotalTimeMillis();
// 记录响应的消息体
logResponseBody(wrappedRequest, wrappedResponse, usedTimes);
}

}


我的做法是实现了 AuthenticationFailureHandler 接口,

@Slf4j
@Component
public class AdminAuthenticationFailureHandler implements AuthenticationFailureHandler {

@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
ApiResult result;
if (e instanceof UsernameNotFoundException || e instanceof BadCredentialsException) {
result = ApiResult.fail(e.getMessage());
} else if (e instanceof LockedException) {
result = ApiResult.fail("账户被锁定,请联系管理员!");
} else if (e instanceof CredentialsExpiredException) {
result = ApiResult.fail("证书过期,请联系管理员!");
} else if (e instanceof AccountExpiredException) {
result = ApiResult.fail("账户过期,请联系管理员!");
} else if (e instanceof DisabledException) {
result = ApiResult.fail("账户被禁用,请联系管理员!");
} else {
log.error("登录失败:", e);
result = ApiResult.fail("登录失败!");
}
ResponseUtils.out(response, result);
}

}


如上所示,在 用户信息通过jwtToken 未查询到时,抛出自定义异常,此token存在于redis中,但是我在redis中删除掉这个token,使程序抛出异常后,预期是走这个实现了AuthenticationFailureHandler接口的类,但是看样子并没有进入这个类中,而postman接受到了类似于springsecurity 自带的返回信息。
{
"timestamp": "2021-05-10T15:32:01.977+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/user/get/1"
}
求问是什么原因导致,自定义异常没有起作用
...全文
979 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
KuKu_Nao 2022-03-30
  • 打赏
  • 举报
回复

您好我遇到跟您同样的问题,请问您解决了吗?是怎么解决的

staton_ 2021-05-13
  • 打赏
  • 举报
回复
引用 11 楼 weixin_43922513 的回复:
引用 10 楼 staton_ 的回复:
[quote=引用 9 楼 weixin_43922513 的回复:][quote=引用 8 楼 staton_ 的回复:][quote=引用 7 楼 weixin_43922513 的回复:][quote=引用 3 楼 staton_ 的回复:][quote=引用 2 楼 weixin_43922513 的回复:]500 是服务器错误,你看一下代码 报什么错
代码报错 是我自定义异常中抛出的错误
AuthenticationFailureHandler 这个是登录失败异常,你那个是登录成功后,验证权限 抛出的异常,所以不会捕捉 [/quote] 我现在是想做一个登出的功能,这个错误是在访问接口的时候抛出异常,那怎样可以捕捉到呢[/quote] 将登出接口,放开,不进行验证[/quote] 什么意思呢?没有明白[/quote] 就是登出接口 不进行拦截[/quote] 登出的接口我这边加入了那个ignore的列表,不进行拦截,登出的时候我删除redis中的信息,但是再次访问,我想让接口进行拦截,返回token不存在,问题是登出的没问题,但是当请求携带着过期的token进来的时候,我在提示错误的时候,并没有提示出我的错误,而是提示了 security自带的500错误
weixin_43922513 2021-05-13
  • 打赏
  • 举报
回复
引用 10 楼 staton_ 的回复:
引用 9 楼 weixin_43922513 的回复:
[quote=引用 8 楼 staton_ 的回复:][quote=引用 7 楼 weixin_43922513 的回复:][quote=引用 3 楼 staton_ 的回复:][quote=引用 2 楼 weixin_43922513 的回复:]500 是服务器错误,你看一下代码 报什么错
代码报错 是我自定义异常中抛出的错误
AuthenticationFailureHandler 这个是登录失败异常,你那个是登录成功后,验证权限 抛出的异常,所以不会捕捉 [/quote] 我现在是想做一个登出的功能,这个错误是在访问接口的时候抛出异常,那怎样可以捕捉到呢[/quote] 将登出接口,放开,不进行验证[/quote] 什么意思呢?没有明白[/quote] 就是登出接口 不进行拦截
staton_ 2021-05-12
  • 打赏
  • 举报
回复
引用 9 楼 weixin_43922513 的回复:
引用 8 楼 staton_ 的回复:
[quote=引用 7 楼 weixin_43922513 的回复:][quote=引用 3 楼 staton_ 的回复:][quote=引用 2 楼 weixin_43922513 的回复:]500 是服务器错误,你看一下代码 报什么错
代码报错 是我自定义异常中抛出的错误
AuthenticationFailureHandler 这个是登录失败异常,你那个是登录成功后,验证权限 抛出的异常,所以不会捕捉 [/quote] 我现在是想做一个登出的功能,这个错误是在访问接口的时候抛出异常,那怎样可以捕捉到呢[/quote] 将登出接口,放开,不进行验证[/quote] 什么意思呢?没有明白
weixin_43922513 2021-05-12
  • 打赏
  • 举报
回复
引用 8 楼 staton_ 的回复:
引用 7 楼 weixin_43922513 的回复:
[quote=引用 3 楼 staton_ 的回复:][quote=引用 2 楼 weixin_43922513 的回复:]500 是服务器错误,你看一下代码 报什么错
代码报错 是我自定义异常中抛出的错误
AuthenticationFailureHandler 这个是登录失败异常,你那个是登录成功后,验证权限 抛出的异常,所以不会捕捉 [/quote] 我现在是想做一个登出的功能,这个错误是在访问接口的时候抛出异常,那怎样可以捕捉到呢[/quote] 将登出接口,放开,不进行验证
staton_ 2021-05-11
  • 打赏
  • 举报
回复
引用 2 楼 weixin_43922513 的回复:
500 是服务器错误,你看一下代码 报什么错
代码报错 是我自定义异常中抛出的错误
weixin_43922513 2021-05-11
  • 打赏
  • 举报
回复
500 是服务器错误,你看一下代码 报什么错
RockeyCui 2021-05-11
  • 打赏
  • 举报
回复
你这个AdminAuthenticationFailureHandler 手动注册了吗?注册方法 HttpSecurity.failureHandler()
staton_ 2021-05-11
  • 打赏
  • 举报
回复
引用 7 楼 weixin_43922513 的回复:
引用 3 楼 staton_ 的回复:
[quote=引用 2 楼 weixin_43922513 的回复:]500 是服务器错误,你看一下代码 报什么错
代码报错 是我自定义异常中抛出的错误
AuthenticationFailureHandler 这个是登录失败异常,你那个是登录成功后,验证权限 抛出的异常,所以不会捕捉 [/quote] 我现在是想做一个登出的功能,这个错误是在访问接口的时候抛出异常,那怎样可以捕捉到呢
weixin_43922513 2021-05-11
  • 打赏
  • 举报
回复
引用 3 楼 staton_ 的回复:
引用 2 楼 weixin_43922513 的回复:
500 是服务器错误,你看一下代码 报什么错
代码报错 是我自定义异常中抛出的错误
AuthenticationFailureHandler 这个是登录失败异常,你那个是登录成功后,验证权限 抛出的异常,所以不会捕捉

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧