SessionManagementFilter 从不调用 SessionAuthenticationStrategy
SessionManagementFilter never calls SessionAuthenticationStrategy
我很难将我们的 Web 应用程序从 Wicket 1.4 迁移到 Wicket 6.20。
我还将 Spring 安全性从以前的(和旧的)版本 2.0.4.
移动到版本 3.2.8.RELEASE
这是 Spring 安全上下文配置的副本:
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant" >
<security:filter-chain request-matcher-ref="requestMatcher"
filters="
securityContextPersistenceFilter,
concurrentSessionFilter,sessionManagementFilter"
pattern="/**" />
</security:filter-chain-map>
</bean>
<beans:bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<beans:constructor-arg ref="securityContextRepository"></beans:constructor-arg>
</beans:bean>
<beans:bean id="sessionManagementFilter"
class="org.springframework.security.web.session.SessionManagementFilter">
<beans:constructor-arg ref="securityContextRepository"></beans:constructor-arg>
<beans:constructor-arg ref="sas"></beans:constructor-arg>
</beans:bean>
<beans:bean id="requestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher" >
<beans:constructor-arg value="/**"></beans:constructor-arg>
</beans:bean>
<beans:bean id="concurrentSessionFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:constructor-arg ref="sessionRegistry" ></beans:constructor-arg>
<beans:constructor-arg value="/petrol/login" ></beans:constructor-arg>
</beans:bean>
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry"/>
<beans:property name="maximumSessions" value="1" />
<beans:property name="exceptionIfMaximumExceeded" value="true" />
</beans:bean>
<beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
</beans:bean>
<beans:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry"/>
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="petrolAuthenticationProvider" />
</beans:list>
</beans:property>
</beans:bean>
<beans:bean name='securityContextRepository'
class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<beans:property name='allowSessionCreation' value='true' />
</beans:bean>
<beans:bean id="petrolAuthenticationProvider"
class="it.loginet.petrol.infrastructure.security.PetrolAuthenticationProvider">
<beans:property name="utenteRepository" ref="utenteRepository" />
</beans:bean>
SessionManagementFilter 应该过滤我们的请求,测试是否允许用户并发登录。
问题是,在验证身份验证是否成功时,SecurityContextRepository 已经包含了 SecurityContext,并且它没有调用 "SessionAuthenticationStrategy.onAuthentication" 方法。
if (!securityContextRepository.containsContext(request)) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && !trustResolver.isAnonymous(authentication)) {
// The user has been authenticated during the current request, so call the session strategy
try {
sessionAuthenticationStrategy.onAuthentication(authentication, request, response);
} catch (SessionAuthenticationException e) {
// The session strategy can reject the authentication
logger.debug("SessionAuthenticationStrategy rejected the authentication object", e);
SecurityContextHolder.clearContext();
failureHandler.onAuthenticationFailure(request, response, e);
return;
}
.........
SaveToSessionResponseWrapper class 在 HttpSession 上保存 SPRING_SECURITY_KEY 属性,SessionManagementFilter 已经在 HttpSession 上找到这个属性并且实际上跳过了内部 SessionAuthenticationStrategy 验证。
我在迁移过程中做错了什么?
好的,我想我找到了解决问题的方法..
SessionManagementFilter,如此处所述 (http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#ftn.d5e3442),无法识别表单登录身份验证,因为我在我的应用程序中使用它。
因此永远不会调用此过滤器内的并发策略..
所以我决定用一个新的 SessionManagementProviderManager
实例扩展 ProviderManager class,覆盖 ProviderManager.authenticate()
方法以应用 1) 使用内部 AuthenticationManager
的初始身份验证过程和 2) SessionAuthenticationStrategy.onAuthentication()
从第 1 点返回的结果验证。
也许这个答案可以帮助遇到同样问题的其他人迁移 Spring 安全..
我很难将我们的 Web 应用程序从 Wicket 1.4 迁移到 Wicket 6.20。 我还将 Spring 安全性从以前的(和旧的)版本 2.0.4.
移动到版本 3.2.8.RELEASE这是 Spring 安全上下文配置的副本:
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant" >
<security:filter-chain request-matcher-ref="requestMatcher"
filters="
securityContextPersistenceFilter,
concurrentSessionFilter,sessionManagementFilter"
pattern="/**" />
</security:filter-chain-map>
</bean>
<beans:bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<beans:constructor-arg ref="securityContextRepository"></beans:constructor-arg>
</beans:bean>
<beans:bean id="sessionManagementFilter"
class="org.springframework.security.web.session.SessionManagementFilter">
<beans:constructor-arg ref="securityContextRepository"></beans:constructor-arg>
<beans:constructor-arg ref="sas"></beans:constructor-arg>
</beans:bean>
<beans:bean id="requestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher" >
<beans:constructor-arg value="/**"></beans:constructor-arg>
</beans:bean>
<beans:bean id="concurrentSessionFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:constructor-arg ref="sessionRegistry" ></beans:constructor-arg>
<beans:constructor-arg value="/petrol/login" ></beans:constructor-arg>
</beans:bean>
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry"/>
<beans:property name="maximumSessions" value="1" />
<beans:property name="exceptionIfMaximumExceeded" value="true" />
</beans:bean>
<beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
</beans:bean>
<beans:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry"/>
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="petrolAuthenticationProvider" />
</beans:list>
</beans:property>
</beans:bean>
<beans:bean name='securityContextRepository'
class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<beans:property name='allowSessionCreation' value='true' />
</beans:bean>
<beans:bean id="petrolAuthenticationProvider"
class="it.loginet.petrol.infrastructure.security.PetrolAuthenticationProvider">
<beans:property name="utenteRepository" ref="utenteRepository" />
</beans:bean>
SessionManagementFilter 应该过滤我们的请求,测试是否允许用户并发登录。 问题是,在验证身份验证是否成功时,SecurityContextRepository 已经包含了 SecurityContext,并且它没有调用 "SessionAuthenticationStrategy.onAuthentication" 方法。
if (!securityContextRepository.containsContext(request)) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && !trustResolver.isAnonymous(authentication)) {
// The user has been authenticated during the current request, so call the session strategy
try {
sessionAuthenticationStrategy.onAuthentication(authentication, request, response);
} catch (SessionAuthenticationException e) {
// The session strategy can reject the authentication
logger.debug("SessionAuthenticationStrategy rejected the authentication object", e);
SecurityContextHolder.clearContext();
failureHandler.onAuthenticationFailure(request, response, e);
return;
}
.........
SaveToSessionResponseWrapper class 在 HttpSession 上保存 SPRING_SECURITY_KEY 属性,SessionManagementFilter 已经在 HttpSession 上找到这个属性并且实际上跳过了内部 SessionAuthenticationStrategy 验证。
我在迁移过程中做错了什么?
好的,我想我找到了解决问题的方法..
SessionManagementFilter,如此处所述 (http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#ftn.d5e3442),无法识别表单登录身份验证,因为我在我的应用程序中使用它。 因此永远不会调用此过滤器内的并发策略..
所以我决定用一个新的 SessionManagementProviderManager
实例扩展 ProviderManager class,覆盖 ProviderManager.authenticate()
方法以应用 1) 使用内部 AuthenticationManager
的初始身份验证过程和 2) SessionAuthenticationStrategy.onAuthentication()
从第 1 点返回的结果验证。
也许这个答案可以帮助遇到同样问题的其他人迁移 Spring 安全..