【问题标题】:Spring+SpringSecurity - AuthenticationEntryPoint Not CalledSpring + SpringSecurity - 未调用AuthenticationEntryPoint
【发布时间】:2019-12-11 12:33:14
【问题描述】:

我使用的是 SpringBoot 2.0.2。我正在尝试使用 Spring Security 实现 JWT 验证。为了处理无效令牌,我抛出了一个运行时异常。我为异常处理添加了自定义 authenticationEntryPoint。对于有效令牌,它运行良好。

当我将它作为 SpringBoot 运行时,它正在工作(并且我收到 401 响应)。但是当我部署它时 作为Tomcat中的WAR(我知道这是错误的),它没有被调用。

如果是 WAR,它会尝试将请求转发到 /error 页面并寻找它的处理方法(请参阅底部的日志)。

最后我得到以下回复:

{
    "timestamp": 1576064959206,
    "status": 500,
    "error": "Internal Server Error",
    "message": "Expired or invalid JWT token",
    "path": "/paymentapi-2.0.2.RELEASE/config/credit"
}

我应该改变什么来获得 401 ?

我有以下配置:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private JwtTokenProvider jwtTokenProvider;

@Autowired
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            .csrf().disable()
            .httpBasic().disable()
            .cors().disable()
            .headers().frameOptions().disable()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/ping").permitAll()
            .antMatchers("/mock/**").permitAll()
            .antMatchers("/customers/**").permitAll()
            .antMatchers("/buyers/**").permitAll()
            .antMatchers("/user/**").hasIpAddress("127.0.0.1")
            .antMatchers("/helper/**").permitAll()
            .antMatchers("/v2/orders/**").permitAll()
            .antMatchers("/transactions/**").permitAll()
            .antMatchers("/paymentCollection/**").permitAll()
            .antMatchers("/paymentRequest").permitAll()
            .antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security",
                    "/swagger-ui.html", "/webjars/**", "/swagger-resources/configuration/ui", "/swagger-ui.html",
                    "/swagger-resources/configuration/security").permitAll()
            .anyRequest().authenticated()
            .and()
            .apply(new JwtConfigurer(jwtTokenProvider))
            .and().exceptionHandling().authenticationEntryPoint(paymentEngineAuthenticationEntryPoint);

}
}

以下是我的自定义身份验证入口点:

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void commence(final HttpServletRequest request, final HttpServletResponse response,
            final AuthenticationException authException) throws IOException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        //response.addHeader("WWW-Authenticate", "Bearer");

        response.setContentType("application/json;charset=UTF-8");
        ResponseData responseData = new ResponseData();
        responseData.setMessage(authException.getMessage());
        responseData.setStatusCode(401);
        responseData.setSuccess(false);
        response.getWriter().write(objectMapper.writeValueAsString(responseData));
        response.flushBuffer();
    }

}

 2019-12-11 16:20:16,178 [DEBUG] [http-nio-8082-exec-7] [o.s.security.web.FilterChainProxy ] /config/credit at position 5 of 11 in additional filter chain; firing Filter: 'JwtTokenAuthenticationFilter' 
        2019-12-11 16:20:16,179 [DEBUG] [http-nio-8082-exec-7] [o.s.s.w.header.writers.HstsHeaderWriter ] Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@229d8736 
        2019-12-11 16:20:16,179 [DEBUG] [http-nio-8082-exec-7] [s.s.w.c.SecurityContextPersistenceFilter] SecurityContextHolder now cleared, as request processing completed 
2019-12-11 16:20:16,179 [DEBUG] [http-nio-8082-exec-7] [o.s.b.w.s.f.OrderedRequestContextFilter ] Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@14816abd 
        2019-12-11 16:20:16,180 [ERROR] [http-nio-8082-exec-7] [o.s.b.w.servlet.support.ErrorPageFilter ] Forwarding to error page from request [/config/credit] due to exception [Expired or invalid JWT token] com.ril.vms.deadpool.exceptions.InvalidJwtAuthenticationException: Expired or invalid JWT token at com.ril.vms.deadpool.securitycore.JwtTokenProvider.validateToken(JwtTokenProvider.java:74) at com.ril.vms.deadpool.securitycore.JwtTokenAuthenticationFilter.doFilterInternal(JwtTokenAuthenticationFilter.java:31) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        ...
        2019-12-11 17:19:15,628 [DEBUG] [http-nio-8082-exec-7] [o.s.web.servlet.DispatcherServlet       ] DispatcherServlet with name 'dispatcherServlet' processing GET request for [/paymentapi-2.0.2.RELEASE/error]
        2019-12-11 17:19:17,556 [DEBUG] [http-nio-8082-exec-7] [s.b.a.e.w.s.WebMvcEndpointHandlerMapping] Looking up handler method for path /error
        2019-12-11 17:19:17,557 [DEBUG] [http-nio-8082-exec-7] [s.b.a.e.w.s.WebMvcEndpointHandlerMapping] Did not find handler method for [/error]
        2019-12-11 17:19:17,557 [DEBUG] [http-nio-8082-exec-7] [a.e.w.s.ControllerEndpointHandlerMapping] Looking up handler method for path /error
        2019-12-11 17:19:17,557 [DEBUG] [http-nio-8082-exec-7] [a.e.w.s.ControllerEndpointHandlerMapping] Did not find handler method for [/error]
        2019-12-11 17:19:17,557 [DEBUG] [http-nio-8082-exec-7] [s.w.s.m.m.a.RequestMappingHandlerMapping] Looking up handler method for path /error
        2019-12-11 17:19:17,558 [DEBUG] [http-nio-8082-exec-7] [s.w.s.m.m.a.RequestMappingHandlerMapping] Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
        2019-12-11 17:19:17,558 [DEBUG] [http-nio-8082-exec-7] [o.s.b.f.s.DefaultListableBeanFactory    ] Returning cached instance of singleton bean 'basicErrorController'

【问题讨论】:

    标签: spring-boot spring-security


    【解决方案1】:

    这就是我解决这个问题的方法:

    1. 在 SpringBootServletInitializer 中我禁用了 ErrorPageFilter

      @SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
      public class MyApplication extends SpringBootServletInitializer {
      
      public static void main(String[] args) {
          SpringApplication.run(MyApplication.class, args);
      }
      
      @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
          return application.sources(MyApplication.class);
      }
      
      public PaymentapiApplication() {
          super();
          setRegisterErrorPageFilter(false);
      }} 
      
    2. 我写了一个自定义过滤器来捕获特定的 RunTimeException

      @Component
      @Order(Ordered.HIGHEST_PRECEDENCE)
      public class ExceptionHandlerFilter extends OncePerRequestFilter {
      
      @Autowired
      private ObjectMapper objectMapper;
      
      @Override
      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse 
      response, FilterChain filterChain)
              throws ServletException, IOException {
      
          try {
              filterChain.doFilter(request, response);
          } catch (RuntimeException e) {
              // custom error response class used across my project
              if(e instanceof InvalidJwtAuthenticationException) {
                  ResponseData responseData = new ResponseData(false, e.getMessage(), 401, 
      null);
                  response.setStatus(HttpStatus.UNAUTHORIZED.value());
                  response.getWriter().write(objectMapper.writeValueAsString(responseData));
              }
          }
      
      }}
      

    这样我得到了 401 响应。

    【讨论】:

      猜你喜欢
      • 2019-06-10
      • 2019-10-10
      • 2011-12-22
      • 2016-09-04
      • 1970-01-01
      • 2019-12-16
      • 1970-01-01
      • 2018-03-03
      • 2020-01-24
      相关资源
      最近更新 更多