【发布时间】:2014-06-09 22:20:09
【问题描述】:
我们正在使用 Spring MVC,并遇到以下与 Remember Me 身份验证相关的问题:
- 选中“记住我”的用户登录,工作正常,persistent_login 表按预期更新
- 我们重新启动应用服务器,可能是在部署等之后
- 用户刷新页面,我们看到图1中的错误消息,用户被重定向到登录页面(没有看到错误)
- 尽管有错误,但persistent_login 条目令牌已更新(系列与刷新前保持一致),spring 记住我令牌也保持不变。
- 用户第二次刷新页面,他们就像什么都没发生一样登录
图 1 -- 错误消息
Apr 24, 2014 9:29:15 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [workmarket] in context with path [] threw exception
java.lang.ClassCastException: org.springframework.security.web.firewall.FirewalledResponse cannot be cast to org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper
at org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext(HttpSessionSecurityContextRepository.java:99)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:139)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:167)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
at com.workmarket.web.authentication.CustomLinkedInLoginFilter.doFilter(CustomLinkedInLoginFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at com.workmarket.web.authentication.CustomLoginFilter.doFilter(CustomLoginFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:86)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
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:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
图 2 -- 安全过滤器
<sec:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
<sec:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
<sec:custom-filter ref="customLoginFilter" position="FORM_LOGIN_FILTER"/>
<sec:custom-filter ref="customLinkedInLoginFilter" after="FORM_LOGIN_FILTER"/>
<sec:custom-filter ref="rememberMeFilter" position="REMEMBER_ME_FILTER"/>
<sec:custom-filter ref="switchUserProcessingFilter" position="SWITCH_USER_FILTER"/>
<sec:custom-filter ref="authenticatedUserInitializer" before="FILTER_SECURITY_INTERCEPTOR"/>
<sec:custom-filter ref="publicWorkRequestFilter" after="FILTER_SECURITY_INTERCEPTOR"/>
<sec:custom-filter ref="securityContextCleanupFilter" after="SESSION_MANAGEMENT_FILTER"/>
<sec:custom-filter ref="customLogoutFilter" position="LOGOUT_FILTER"/>
图 3 -- 记住我设置
<!-- Remember me -->
<bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<constructor-arg index="0" ref="org.springframework.security.authenticationManager"/>
<constructor-arg index="1" ref="rememberMeServices"/>
</bean>
<bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<constructor-arg index="0" value="[REMOVED]"/>
</bean>
<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<constructor-arg index="0" value="[REMOVED]"/>
<constructor-arg index="1" ref="userDetailsService"/>
<constructor-arg index="2" ref="persistentTokenRepository"/>
</bean>
版本
- spring 框架 -- 3.2.4.RELEASE
- spring security -- 3.1.0.RELEASE
- spring-security-saml2-core -- 1.0.0.RC2
- opensaml -- 2.5.3
====== 更新 ======
我们发现删除这两个与 SAML 相关的过滤器可以解决此问题,但我们确实需要这些过滤器才能正常工作...
<sec:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
<sec:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
====== 更新 2 ======
samlFilter 定义的详细信息。
<bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map request-matcher="ant">
<security:filter-chain pattern="/saml/login/**" filters="samlEntryPoint"/>
<security:filter-chain pattern="/saml/SSO/**" filters="samlWebSSOProcessingFilter"/>
</security:filter-chain-map>
</bean>
<bean id="samlEntryPoint" class="org.springframework.security.saml.SAMLEntryPoint">
<property name="defaultProfileOptions">
<bean class="org.springframework.security.saml.websso.WebSSOProfileOptions">
<property name="includeScoping" value="false"/>
</bean>
</property>
</bean>
<bean id="samlWebSSOProcessingFilter" class="org.springframework.security.saml.SAMLProcessingFilter">
<property name="authenticationManager" ref="samlAuthenticationManager"/>
<property name="authenticationSuccessHandler">
<bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/"/>
</bean>
</property>
</bean>
提前致谢。
【问题讨论】:
-
您可以尝试使用 Spring Security 3.1.6.RELEASE 吗?如果这不起作用,您可以尝试 3.1.2.RELEASE,它与示例应用程序使用的版本相同。
-
两个版本都试过了,还是遇到这个问题。这一定与 SAML 过滤器有关。
-
您是否尝试仅删除两个过滤器之一并查看是否会产生错误?您能否为导致问题的两个过滤器提供 bean 定义。
-
绝对是 samlFilter,删除它,一切都会恢复正常。我将在上面添加 samlFilter bean 定义。
标签: spring-mvc spring-security remember-me