Spring security 身份验证失败时引发异常
我在我的Spring security 身份验证失败时引发异常,spring-security,exception-handling,spring-boot,Spring Security,Exception Handling,Spring Boot,我在我的springboot应用程序中实现了一些基于令牌的身份验证。我有一个过滤器,在该过滤器中,我执行以下操作: @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequ
springboot
应用程序中实现了一些基于令牌的身份验证。我有一个过滤器,在该过滤器中,我执行以下操作:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String authToken = httpRequest.getHeader("X-TOKEN-AUTH");
String username = null;
if (securityEnabled) {
if (authToken != null) {
try {
username = userTokenService.validateToken(authToken);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), null, userDetails.getAuthorities());
auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(auth);
} catch (AuthenticationException ae) {
//TODO log something about signature exception
log.warn(ae.getMessage());
}
}
}
chain.doFilter(request, response);
}
我还有一个自定义AuthFailureHandler:
@Component
public class AuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.write(exception.getMessage());
writer.flush();
}
}
我的代码username=userTokenService.validateToken(authToken)由于各种原因,代码>引发身份验证异常AuthenticationException
是扩展exception
的自定义异常。当我捕获到这个异常时,我仍然希望返回401,但我希望我的消息显示在当前由Spring Security
以JSON形式发送回来的默认消息中:
{
"timestamp": 1463408604943,
"status": 401,
"error": "Unauthorized",
"message": "An Authentication object was not found in the SecurityContext",
"path": "/api/brands/2"
}
例如,我想
{
"timestamp": 1463408604943,
"status": 401,
"error": "Unauthorized",
"message": "Invalid Token: Expired",
"path": "/api/brands/2"
}
我不确定如何覆盖这种行为。所以……我终于找到了答案。问题是过滤器在食物链中的位置更高,所以它们实际上不太涉及春天。当我在过滤器中抛出异常时,Spring不一定会捕获它。过滤器将抛出500并显示异常消息。要修复它,我只需在过滤器中捕获我的异常,然后使用适当的http状态调用senderro
try {
username = userTokenService.validateToken(authToken);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), null, userDetails.getAuthorities());
auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(auth);
chain.doFilter(request, response);
return;
} catch (Exception ex) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.getMessage());
return;
}
catch
中的return
语句是这样的:chain.doFilter(请求、响应)没有调用doFilter
方法末尾的code>。所以…我终于解决了这个问题。问题是过滤器在食物链中的位置更高,所以它们实际上不太涉及春天。当我在过滤器中抛出异常时,Spring不一定会捕获它。过滤器将抛出500并显示异常消息。要修复它,我只需在过滤器中捕获我的异常,然后使用适当的http状态调用senderro
try {
username = userTokenService.validateToken(authToken);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), null, userDetails.getAuthorities());
auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(auth);
chain.doFilter(request, response);
return;
} catch (Exception ex) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.getMessage());
return;
}
catch
中的return
语句是这样的:chain.doFilter(请求、响应)不调用doFilter
方法末尾的code>。此AuthenticationException
是您的自定义异常或spring的AuthenticationException
?它是我自己的自定义异常类此AuthenticationException
是您的自定义异常或spring的AuthenticationException
?它是我自己的自定义异常类