我有一个扩展OncePerRequestFilter
的JWTAuthFilter,我在这里验证令牌。
validateToken方法抛出自定义异常(扩展org.springframework.security.core.AuthenticationException
的CredentialsChangedException和TooManyDevicesException )
这些异常在过滤器中被正确捕获,但是当它们前进到AuthenticationEntryPoint
时,AuthenticationException变成一个instanceof
InsufficientAuthenticationException
,并且我希望作为响应返回的自定义错误消息丢失。
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
private static final String BEARER = "Bearer ";
private static final Logger logger = LoggerFactory.getLogger(JwtAuthFilter.class);
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Value ("${jwt.http.request.header}")
private String tokenHeader;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String requestTokenHeader = request.getHeader(this.tokenHeader);
String username = null;
String jwtToken = null;
if((requestTokenHeader != null) && requestTokenHeader.startsWith(BEARER)) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
if((username != null) && (SecurityContextHolder.getContext()
.getAuthentication() == null)) {
UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
if(jwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(userDetails, null,
userDetails.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext()
.setAuthentication(usernamePasswordAuthenticationToken);
}
}
}
catch (IllegalArgumentException e) {
logger.error("Unable to get username from JWT. ", e.getLocalizedMessage());
}
catch (ExpiredJwtException e) {
logger.warn("Expired JWT. ", e.getLocalizedMessage());
}
catch (Exception e) {
logger.error(e.getLocalizedMessage());
}
}
chain.doFilter(request, response);
}
}
@Component
public class JwtUnAuthorizedResponseAuthenticationEntryPoint implements AuthenticationEntryPoint , Serializable {
private static final long serialVersionUID = - 8970718410437077606L;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
throws IOException {
if(e instanceof TooManyDevicesException) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, Constants.TOO_MANY_DEVICES);
}
else if(e instanceof CredentialsChangedException) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, Constants.CREDENTIALS_CHANGED);
}
else {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, Constants.JWT_EXPIRED);
}
}
}
我想从我的过滤器发送一个适当的未经授权的响应,有没有办法做到这一点?
https://stackoverflow.com/questions/56449140
复制相似问题