java - SessionManagementFilter 从不调用 SessionAuthenticationStrategy

标签 java spring spring-security wicket-6

我在将 Web 应用程序从 Wicket 1.4 迁移到 Wicket 6.20 时遇到了困难。 我还将 Spring Security 从之前的(旧的)版本 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 类在 HttpSession 上保存 SPRING_SECURITY_KEY 属性,SessionManagementFilter 已经在 HttpSession 上找到此属性,并实际上跳过内部 SessionAuthenticationStrategy 验证。

我在迁移过程中做错了什么?

最佳答案

好的,我想我找到了解决问题的方法..

SessionManagementFilter,如此处所述 ( http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#ftn.d5e3442 ),无法识别表单登录身份验证,因为我在应用程序中使用它。 因此,这个过滤器内的并发策略永远不会被调用。

因此,我决定使用新的 SessionManagementProviderManager 实例扩展 ProviderManager 类,重写 ProviderManager.authenticate() 方法以应用 1) 使用内部 AuthenticationManager 的初始身份验证过程 和 2)SessionAuthenticationStrategy.onAuthentication() 处理从第 1) 点返回的结果身份验证。

也许这个答案可以帮助其他人在迁移 Spring Security 时遇到同样的问题..

关于java - SessionManagementFilter 从不调用 SessionAuthenticationStrategy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39632577/

相关文章:

netbeans 中的 Java 程序无法正常运行,但在调试时工作得很好

java - 用 java.lang.Boolean 和 switch 做三元逻辑

java - 组织.postgresql.util.PSQLException : No value specified for parameter 1

java - 有没有办法在 Spring MVC 测试中不使用 @MockBean?

mysql - 原因 : PreparedStatementCallback; bad SQL grammar

java - Spring 安全: User Authorization in Java Class

java - Google App Engine(Java)App停止运行(所有版本)

c# - 存储和查询邮政地址

java - 尽管 saveOrUpdate 失败,但版本已增加

java - 在 Spring Security 中创建自定义 PostAuthorize 方法