首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在AuthenticationEntryPoint中捕获从OncePerRequestFilter的子类引发的自定义异常

在AuthenticationEntryPoint中捕获从OncePerRequestFilter的子类引发的自定义异常
EN

Stack Overflow用户
提问于 2019-06-05 02:00:29
回答 2查看 780关注 0票数 0

我有一个扩展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);
        }

    }
}

我想从我的过滤器发送一个适当的未经授权的响应,有没有办法做到这一点?

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56449140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档