Java 如何使用JWT身份验证处理API REST上的身份验证异常?

Java 如何使用JWT身份验证处理API REST上的身份验证异常?,java,spring,spring-security,Java,Spring,Spring Security,我实现了一个使用Spring安全性和JWT的API REST 除了尝试处理身份验证提供程序引发的异常外,所有这些都可以正常工作 以下是我的安全配置功能: @Override protected void configure(final HttpSecurity http) throws Exception { http .csrf().disable().formLogin().disable() .httpBasic().disable().logout().disab

我实现了一个使用Spring安全性和JWT的API REST

除了尝试处理身份验证提供程序引发的异常外,所有这些都可以正常工作

以下是我的安全配置功能:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
    .csrf().disable().formLogin().disable()
    .httpBasic().disable().logout().disable() 
    .sessionManagement().sessionCreationPolicy(STATELESS)
    .and().authorizeRequests().requestMatchers(PROTECTED_URLS).authenticated()
    .and().authenticationProvider(tokenAuthenticationProvider)
        .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException failed) throws IOException, ServletException {
    int status = ...
    String jsonString = ...
    response.setStatus(status);
    response.setContentType("application/json");
    response.getWriter().write(jsonString); 
}
正如您所见,为了使用我使用io.jsonwebtoken实现的JWT服务,我使用了一个定制的提供程序和过滤器,所以不必担心安全漏洞

我使用ResponseEntityExceptionHandler处理大多数异常。但此处理程序不捕获在提供程序上引发的异常

因此,我尝试实现AuthenticationEntryPoint来处理这些异常。但那没用

我发现我的自定义AbstractAuthenticationProcessingFilter正在缓存提供程序上引发的身份验证异常。我试图重新抛出异常,但入口点没有缓存它

现在,我正在解决unsuccessfulAuthentication函数的AbstractAuthenticationProcessingFilter上的这些异常:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
    .csrf().disable().formLogin().disable()
    .httpBasic().disable().logout().disable() 
    .sessionManagement().sessionCreationPolicy(STATELESS)
    .and().authorizeRequests().requestMatchers(PROTECTED_URLS).authenticated()
    .and().authenticationProvider(tokenAuthenticationProvider)
        .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException failed) throws IOException, ServletException {
    int status = ...
    String jsonString = ...
    response.setStatus(status);
    response.setContentType("application/json");
    response.getWriter().write(jsonString); 
}

我不太喜欢这个解决方案,我更愿意将这些异常与AbstractAuthenticationProcessingFilter分开处理。

异常由ExceptionTranslationFilter处理

如果异常类型为org.springframework.security.core.AuthenticationException any子类,则它将流入AuthenticationEntryPoint,这听起来似乎不适合您。 如果异常类型为org.springframework.security.access.AccessDeniedException或子类,则它将流入AccessDeniedHandler。 将重新引发任何其他异常。 如果您希望处理任何其他类别中的内容,您可以在过滤器链的更高层实现您自己的过滤器,或者按照您所做的操作来处理它。有关更多信息,请参阅上的部分。下面是如何实现的


注意:正如其他评论者所指出的,如果有现成的解决方案满足您的JWT需求,通常建议您呆在家附近。但是,实现过滤器以添加到Spring Security过滤器链是为您自己的应用程序扩展Spring Security功能的一个非常好的方法。在许多用例中,您会发现这是一种有用且必要的方法。

我已经阅读了您的代码大约5次,但我无法真正理解您想要做什么。Spring有一个实现的ExceptionTranslationFilter,它将捕获filterchain中所有抛出的AccessDeniedException和AuthenticationException。BadCredentialException是AuthenticationException的子类型,因此会捕获它并将其转换为正确的状态代码。我不明白的是,为什么在spring中已经有大量可定制的过滤器,您可以根据自己的需要使用和定制,而您却要编写大量定制过滤器。此外,AuthenticationEntryPoint是实现登录初始值设定项的上下文接口。它不是一个捕捉异常的类。如果您查看api,您可以看到已经实现了哪些类型,例如BasicAuthenticationPoint基本身份验证、BealerTokenAuthenticationEntryPoint oauth2和令牌等。我建议您阅读spring security中的jwt是如何工作的,并使用推荐的方式实现它@谢谢你的评论。身份验证逻辑运行良好,因此无需重新实现,因为它不知道spring以这种方式支持JWT。为了使用JWT的自定义实现,需要自定义过滤器。我正在使用一个库。现在我只是删除了入口点,我只是在处理过滤器上的异常,我认为这不是很漂亮。我正在编辑这个问题,用我在过去所做的更改来澄清。