Я пытаюсь аутентифицировать пользователей с токеном JWT в Spring Security. У меня есть один класс - JWTFilter, который расширяет интерфейс OncePerRequest и реализует метод doFilterInternal. В этом методе у меня есть исключение.
Вот определение класса JWTFilter.
public class JWTFilter extends OncePerRequestFilter {
@Value("${jwt.header}")
private String header;
private TokenUtil tokenUtil;
public JWTFilter(TokenUtil tokenUtil) {
this.tokenUtil = tokenUtil;
}
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain) throws
ServletException, IOException {
String jwt = resolveToken(httpServletRequest);
if (StringUtils.hasText(jwt) && this.tokenUtil.validateToken(jwt)) {
Authentication authentication =
this.tokenUtil.getAuthentication(jwt);
SecurityContextHolder.getContext()
.setAuthentication(authentication);
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(header);
return (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer "))
? bearerToken.substring(7, bearerToken.length())
: null;
}
}
Каждый раз, когда filterChain.doFilter(httpServletRequest, httpServletResponse);
вызывается выбрасывает следующее исключение:
java.lang.IllegalStateException: не удается создать сеанс после того, как ответ был зафиксирован
в org.apache.catalina.connector.Request.doGetSession (Request.java:2983) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.connector.Request.getSession (Request.java:2416) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.connector.RequestFacade.getSession (RequestFacade.java:908) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.connector.RequestFacade.getSession (RequestFacade.java:920) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
at javax.servlet.http.HttpServletRequestWrapper.getSession (HttpServletRequestWrapper.java:250) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
at javax.servlet.http.HttpServletRequestWrapper.getSession (HttpServletRequestWrapper.java:250) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
at javax.servlet.http.HttpServletRequestWrapper.getSession (HttpServletRequestWrapper.java:250) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.camunda.bpm.webapp.impl.security.auth.AuthenticationFilter.doFilter (AuthenticationFilter.java:68) ~ [camunda-webapp-7.11.0-classes.jar: 7.11.0]
в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:101) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.springframework.web.filter.RequestContextFilter.doFilterInternal (RequestContextFilter.java:99) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:320) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke (FilterSecurityInterceptor.java:127) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter (FilterSecurityInterceptor.java:91) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter.java:119) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.session.SessionManagementFilter.doFilter (SessionManagementFilter.java:137) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter (AnonymousAuthenticationFilter.java:111) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter (SecurityContextHolderAwareRequestFilter.java:170) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter (RequestCacheAwareFilter.java:63) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
на com.logate.lts.core.security.jwt.JWTFilter.doFilterInternal (JWTFilter.java:40) ~ [classes /: na]
at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.authentication.logout.LogoutFilter.doFilter (LogoutFilter.java:116) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal (HeaderWriterFilter.java:74) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter (SecurityContextPersistenceFilter.java:105) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal (WebAsyncManagerIntegrationFilter.java:56) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy.doFilterInternal (FilterChainProxy.java:215) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.security.web.FilterChainProxy.doFilter (FilterChainProxy.java:178) ~ [spring-security-web-5.1.5.RELEASE.jar: 5.1.5.RELEASE]
в org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:357) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.springframework.web.filter.DelegatingFilterProxy.doFilter (DelegatingFilterProxy.java:270) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.springframework.web.filter.FormContentFilter.doFilterInternal (FormContentFilter.java:92) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal (HiddenHttpMethodFilter.java:93) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:200) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) ~ [spring-web-5.1.6.RELEASE.jar: 5.1.6.RELEASE]
в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:200) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:96) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:490) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:139) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:92) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:74) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:343) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.coyote.http11.Http11Processor.service (Http11Processor.java:408) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.coyote.AbstractProcessorLight.process (AbstractProcessorLight.java:66) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.coyote.AbstractProtocol $ ConnectionHandler.process (AbstractProtocol.java:834) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun (NioEndpoint.java:1415) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в org.apache.tomcat.util.net.SocketProcessorBase.run (SocketProcessorBase.java:49) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в java.base / java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1128) ~ [na: na]
в java.base / java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:628) ~ [na: na]
в org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run (TaskThread.java:61) ~ [tomcat-embed-core-9.0.17.jar: 9.0.17]
в java.base / java.lang.Thread.run (Thread.java:835) ~ [na: na]
Вот моя конфигурация безопасности:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint;
private TokenUtil tokenUtil;
@Override
public void configure(WebSecurity web) throws Exception
{
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**")
.antMatchers("/websocket/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
// we don't need CSRF because our token is invulnerable
.csrf().disable()
.headers().frameOptions().disable().and()
//.headers().cacheControl().disable().and()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.exceptionHandling().authenticationEntryPoint(http401UnauthorizedEntryPoint).and()
.authorizeRequests()
// allow anonymous resource requests on login and reset password
.antMatchers("/api/user/authenticate").permitAll()
.antMatchers("/api/active-directory/authenticate").permitAll()
.antMatchers("/api/admin/**").permitAll()
.antMatchers("/api/cockpit/**").permitAll()
.antMatchers("/api/tasklist/**").permitAll()
.antMatchers("/api/engine/**").permitAll()
.antMatchers("/rest/**").permitAll()
.antMatchers("/api/**").authenticated();
// any other request needs authentication
//.anyRequest().authenticated();
// Custom JWT based security filter
http.addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JWTFilter jwtFilter() {
return new JWTFilter(tokenUtil);
}
@Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder,
CustomUserDetailsServiceImpl userDetailsService) throws Exception
{
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Autowired
public void setHttp401UnauthorizedEntryPoint(Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint) {
this.http401UnauthorizedEntryPoint = http401UnauthorizedEntryPoint;
}
@Autowired
public void setTokenUtil(TokenUtil tokenUtil) {
this.tokenUtil = tokenUtil;
}
}