Spring boot 弹簧&x2B;SpringSecurity-未调用AuthenticationEntryPoint
我正在使用SpringBoot 2.0.2。我正在尝试使用Spring安全性实现JWT验证。要处理无效令牌,我将引发运行时异常。我为异常处理添加了自定义authenticationEntryPoint。对于有效令牌,它工作得非常好 当我作为SpringBoot运行它时,它正在工作(我得到了401响应)。但当我部署它时 因为Tomcat中的战争(我知道这是错误的),所以它不会被调用。 在WAR的情况下,它试图将请求转发到/error页面,并查找其处理程序方法(请参阅底部的日志) 最后,我得到以下回应:Spring boot 弹簧&x2B;SpringSecurity-未调用AuthenticationEntryPoint,spring-boot,spring-security,Spring Boot,Spring Security,我正在使用SpringBoot 2.0.2。我正在尝试使用Spring安全性实现JWT验证。要处理无效令牌,我将引发运行时异常。我为异常处理添加了自定义authenticationEntryPoint。对于有效令牌,它工作得非常好 当我作为SpringBoot运行它时,它正在工作(我得到了401响应)。但当我部署它时 因为Tomcat中的战争(我知道这是错误的),所以它不会被调用。 在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'
@组件
公共类CustomAuthenticationEntryPoint实现AuthenticationEntryPoint{
@自动连线
私有对象映射器对象映射器;
@凌驾
公共无效开始(最终HttpServletRequest请求,最终HttpServletResponse响应,
最终身份验证异常(authException)引发IOException{
response.setStatus(HttpServletResponse.SC_未经授权);
//addHeader(“WWW认证”、“承载人”);
setContentType(“application/json;charset=UTF-8”);
ResponseData ResponseData=新ResponseData();
responseData.setMessage(authException.getMessage());
响应数据设置状态代码(401);
responseData.setSuccess(假);
response.getWriter().write(objectMapper.writeValueAsString(responseData));
response.flushBuffer();
}
}
2019-12-11 16:20:16178[DEBUG][http-nio-8082-exec-7][o.s.security.web.FilterChainProxy]/config/credit位于附加过滤器链中11个位置中的第5个位置;正在启动筛选器:“JwtTokenAuthenticationFilter”
2019-12-11 16:20:16179[DEBUG][http-nio-8082-exec-7][o.s.s.w.header.writers.HstsHeaderWriter]未注入HSTS头,因为它与请求匹配程序org.springframework.security.web.header.writers.HstsHeaderWriter不匹配$SecureRequestMatcher@229d8736
2019-12-11 16:20:16179[调试][http-nio-8082-exec-7][s.s.w.c.SecurityContextPersistenceFilter]随着请求处理完成,SecurityContextHolder现在已清除
2019-12-11 16:20:16179[调试][http-nio-8082-exec-7][o.s.b.w.s.f.OrderedRequestContextFilter]已清除线程绑定请求上下文:org.apache.catalina.connector。RequestFacade@14816abd
2019-12-11 16:20:16180[错误][http-nio-8082-exec-7][o.s.b.w.servlet.support.ErrorPageFilter]由于异常[过期或无效的JWT令牌]从请求[/config/credit]转发到错误页com.ril.vms.deadpool.exceptions.InvalidJwtAuthenticationException:com.ril.vms.deadpool.securitycore.JwtTokenProvider.validateToken(JwtTokenProvider.java:74)处com.ril.vms.deadpool.securitycore.JwtTokenAuthenticationFilter.doFilterInternal(JwtTokenAuthenticationFilter.java:31)处的JwtTokenProvider令牌过期或无效位于org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
...
2019-12-11 17:19:15628[DEBUG][http-nio-8082-exec-7][o.s.web.servlet.DispatcherServlet]名为“DispatcherServlet”的DispatcherServlet正在处理对[/paymentapi-2.0.2.发布/错误]的GET请求
2019-12-11 17:19:17556[调试][http-nio-8082-exec-7][s.b.a.e.w.s.WebMvcEndpointHandlerMapping]查找路径/错误的处理程序方法
2019-12-11 17:19:17557[DEBUG][http-nio-8082-exec-7][s.b.a.e.w.s.WebMvcEndpointHandlerMapping]未找到[/error]的处理程序方法
2019-12-11 17:19:17557[调试][http-nio-8082-exec-7][a.e.w.s.ControllerEndpointHandlerMapping]查找路径/错误的处理程序方法
2019-12-11 17:19:17557[调试][http-nio-8082-exec-7][a.e.w.s.ControllerEndpointHandlerMapping]未找到[/error]的处理程序方法
2019-12-11 17:19:17557[调试][http-nio-8082-exec-7][s.w.s.m.m.a.RequestMappingHandlerMapping]查找路径/错误的处理程序方法
2019-12-11 17:19:17558[DEBUG][http-nio-8082-exec-7][s.w.s.m.a.RequestMappingHandlerMapping]返回处理程序方法[public org.springframework.http.ResponseEntity org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
2019-12-11 17:19:17558[调试][http-nio-8082-exec-7][o.s.b.f.s.DefaultListableBeanFactory]返回单例bean“basicErrorController”的缓存实例
我就是这样解决这个问题的:
@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);
}}
@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响应。我就是这样解决这个问题的:
@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);
}}
@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));
}
}
}}