我有一个springboot 2.0.2应用程序/ spring web security 5.0.5 /嵌入式Tomcat 8,它在一段时间不活动后收到CookieTheftException。
我正在使用"持久令牌方法"如下所述:https://docs.spring.io/spring-security/site/docs/5.0.5.RELEASE/reference/htmlsingle/#remember-me我的PERSISTENT_USERS表中插入了数据。
事件虽然我试图配置很长的超时(90天),但会话似乎在几个小时后超时。通过浏览器进行的任何进一步活动都会导致使用现代Firefox和Chrome浏览器的CookieTheft异常。
[04-06-2018 09:24:10.890] [https-jsse-nio-7001-exec-4] [ERROR] [o.a.c.c.C.[Tomcat].[localhost]] - Exception Processing ErrorPage[errorCode=0, location=/error]
org.springframework.security.web.authentication.rememberme.CookieTheftException: Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
at org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices.processAutoLoginCookie(PersistentTokenBasedRememberMeServices.java:119)
at org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.autoLogin(AbstractRememberMeServices.java:136)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:98)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:472)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:395)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:395)
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:254)
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:349)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:175)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
以下是我的WebSecurityConfig的样子:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
private final static String COOKIE_STRING = "my_cookie";
@Inject
private MyUserDetailsService userSvc;
@Inject
private DataSource datasource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(authenticationProvider());
}
@Bean
public DaoAuthenticationProvider authenticationProvider()
{
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userSvc);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
{
httpSecurity
.authorizeRequests()
.antMatchers("/webjars/**","/forgotMyPassword","/mobile-manifest.json","/service-worker.js").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.loginProcessingUrl("/login")
.successHandler(savedRequestAwareAuthenticationSuccessHandler())
.successForwardUrl("/main")
.failureUrl("/login?loginFailed=true")
.and()
.logout().logoutUrl("/logout")
.permitAll()
.logoutSuccessUrl("/login?logoutSuccess=true")
.deleteCookies(COOKIE_STRING)
.and()
.rememberMe().tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(7776000); /* 60 sec * 60 min * 24 hours * 90 days */
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/css/**", "/js/**", "/images/**", "/icons/**", "/googlemaps/**");
}
@Bean
public PersistentTokenRepository persistentTokenRepository()
{
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(datasource);
return db;
}
@Bean
public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler()
{
SavedRequestAwareAuthenticationSuccessHandler auth = new SavedRequestAwareAuthenticationSuccessHandler();
auth.setTargetUrlParameter("targetUrl");
return auth;
}
@Bean
public PasswordEncoder passwordEncoder()
{
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
其他stackoverflow帖子/问题帮助我做到了这一点,但还没有完全成功地工作。