我有一个使用SpringSecurity3.1.2的GWT应用程序在tomcat 7中运行。我正在使用UsernamePasswordAuthenticationFilter和PersistentTokenBasedRememberMeServices来持久化数据库上的登录。此外,我也在使用Tomcat PersistentManager将会话保存在数据库中。现在我的问题是每次尝试登录时都会收到 * 无效的remember-me令牌(系列/令牌)不匹配CookieTheftException*(我在下面添加了堆栈)。我尝试从tomcat_sessions表中删除会话,如下所示
1.关机雄猫
1.从tomcat_sessions表中删除记录
1.启动Tomcat
1.尝试再次登录到我收到CookieTheftException的应用程序...
我还注意到,即使在删除了Tomcat_Sessions表中的所有记录之后,当我重新启动Tomcat时,Tomcat_Sessions也会被我之前删除的所有会话填满。
我还删除了Spring persistent_logins表中的所有记录,并禁用了Tomcat PersistentManager,但仍然存在相同的问题...
知道是什么问题吗?谢谢
SEVERE: Servlet.service() for servlet [springMvcServlet] in context with path [/brate] threw exception
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:102)
at org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.autoLogin(AbstractRememberMeServices.java:115)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.brate.admin.server.servlet.crawler.GoogleBotFilter.doFilter(GoogleBotFilter.java:202)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
4条答案
按热度按时间k3bvogb11#
为了让我们达成共识,我将首先花一分钟来解释我是如何理解这种持久令牌机制的工作原理的。
从头开始(
persistent_logins
表中没有条目):只要用户仍然具有活动会话,则在认证时将不调用记住我功能。
为了在很大程度上避免CookieTheftException,请确保对Web应用内容(如图像、字体、脚本等)的请求不经过Springs身份验证过滤器。为此,只需在常规安全配置之上添加另一个
<http>
配置,并指定您不希望对资源请求进行任何安全保护(使用相关路径,而不是/resources/**
):(For Java配置请参见此处:How do I define http "security = 'none' in JavaConfig?)
如果你从数据库中删除了一个用户的令牌(并且他们的会话已经过期),那么这个用户将在下一次请求时被注销。所以你所说的自动重新创建持久令牌(在
persistent_logins
表中)是没有意义的,我非常怀疑这种情况。PersistentTokenRepository
的createNewToken(PersistentRememberMeToken token)
方法只在登录成功时被调用。最后,如果您仍然会得到异常,则附加
PersistentTokenBasedRememberMeServices
的源代码并在processAutoLoginCookie
方法中放置一个断点以查看哪个请求导致了CookieTheftException会有所帮助。希望这能帮上忙。
k75qkfdt2#
我遇到了同样的错误,注意到它试图自动登录安全链被忽略的每个请求。
在此之后,我注意到js文件和css文件跳过了安全链,我删除了这些Map,并记得我开始工作,因为它应该。
8ljdwjyq3#
我的配置中缺少的部分是RememberMeAuthenticationProvider。(http://docs.spring.io/spring-security/站点/docs/3.2.2.RELEASE/参考/htmlsingle/#记住我的实现)
请注意,RememberMeAuthenticationProvider的包已更改,与文档中的包不同。
这是我的配置:
马库斯·库切的回答让我明白了一切。谢谢!
jgovgodb4#
修正了令牌历史记录的问题-从这个评论中得到了这个想法
1.实现remember me service以检查多个令牌而不是最后一个令牌
要模拟
PersistentTokenBasedRememberMeServices
的原始行为,可以将.limit(1)
添加到CustomPersistentTokenRepository.findAllBySeries
方法