3

我是 Spring Security 的新手。我需要进行基于 URL 的身份验证,其中用户需要根据每次作为 URL 中的参数发送的唯一引用进行身份验证。我会将这个引用传递给 Web 服务,获取所需的数据,然后对用户进行身份验证(并设置角色)。身份验证和授权部分工作正常。

但是,当我尝试再次访问应用程序(现在在 URL 中使用不同的引用)时,它显示“SecurityContextHolder 未填充匿名令牌,因为它已经包含......”并且它显示了先前请求的详细信息。我尝试使用 SecurityContextHolder.getContext().setAuthentication(null) 和 SecurityContextHolder.clearContext() 清除安全上下文。

在此之后,我能够多次访问该应用程序。但是,如果我尝试从同事的机器上同时访问该应用程序,我会得到一个空白页。检查日志后,我看到一条消息“SecurityContextHolder 未填充匿名令牌......”。我也尝试过设置会话,但我不知道我在哪里丢失了轨道。

下面是我的 web.xml(只有 spring 安全部分):

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>
          org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<listener>
    <listener-class>
          org.springframework.security.web.session.HttpSessionEventPublisher
    </listener-class>
</listener>

<session-config>
<session-timeout>30</session-timeout>
</session-config>

弹簧安全.xml:

<http use-expressions="true" auto-config="false" entry-point-                   
                            ref="http403ForbiddenEntryPoint">
<intercept-url pattern="/paymentPortalInternal.*" access="hasRole('Internal')"/>
<intercept-url pattern="/paymentPortalExternal.*" access="hasRole('External')"/>

<custom-filter position="PRE_AUTH_FILTER" ref="customAuthenticationFilter"/>
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<session-management session-authentication-strategy-ref="sas"/>
</http>

<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/session-expired.htm" />
</beans:bean>

<beans:bean id="http403ForbiddenEntryPoint"
  class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<beans:bean id="customAuthenticationFilter"
  class="com.xxx.xxx.xxxxx.security.CustomAuthenticationFilter">
      <beans:property name="sessionAuthenticationStrategy" ref="sas" />
  <beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>

<beans:bean id="sas" 
              class="org.springframework.security.web.authentication.session.
                                               ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
<beans:property name="exceptionIfMaximumExceeded" value="true" />
</beans:bean>

<beans:bean id="sessionRegistry"    
class="org.springframework.security.core.session.SessionRegistryImpl" />

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="preauthAuthProvider" />
</authentication-manager>

<beans:bean id="preauthAuthProvider" 
                class="org.springframework.security.web.authentication.preauth.
                                       PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService">
    <beans:bean class="com.XXX.XXXX.XXX.UserServiceImpl" />
    </beans:property>
</beans:bean>

如果我需要提供更多信息,请告诉我。

编辑:添加日志。

对于第一个请求:

2013-02-07 17:27:38,834 调试 [http-8081-2][org.springframework.security.web.context.HttpSessionSecurityContextRepository.readSecurityContextFromSession(127)] - 当前不存在 HttpSession 2013-02-07 17:27: 38,834 调试 [http-8081-2][org.springframework.security.web.context.HttpSessionSecurityContextRepository.loadContext(85)] - HttpSession 中没有可用的 SecurityContext:null。将创建一个新的。

对于第二个请求(请注意,安全上下文中的详细信息是第一个请求的详细信息):

2013-02-07 17:27:54,272 调试 [http-8081-2][org.springframework.security.web.context.HttpSessionSecurityContextRepository.readSecurityContextFromSession(158)] - 从 SPRING_SECURITY_CONTEXT: 'org.springframework.security .core.context.SecurityContextImpl@1017293c:身份验证:org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken@1017293c:主体:org.springframework.security.core.userdetails.User@35cd3811:用户名:Internal@5581e6e1-7e61 -41bb-9257-b3c1acb96519;密码保护]; 启用:真;AccountNonExpired:真;凭据非过期:真;AccountNonLocked:真;授予权限:内部;凭证:[受保护];已认证:真实;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@ffffc434:RemoteIpAddress:10.188。182.107;会话ID:空;授予权限:内部'

我的理解是安全上下文持有者存储所有用户的详细信息。但在这种情况下,我无法从不同的选项卡/浏览器启动应用程序。

4

2 回答 2

1

我能够通过覆盖默认过滤器链(使用过滤器链代理)并仅调用所需的过滤器来解决此问题。感谢 LukeTaylor 和 Ketan 的建议。请让我知道是否有人有同样的问题。我可以发布我的 XML 和其他东西。

于 2013-02-18T10:00:00.033 回答
1

如果您的 CustomAuthenticationFilter 正在扩展AbstractPreAuthenticatedProcessingFilter,则以下 2 个属性可能会让您有所了解。1. checkForPrincipalChanges 2.invalidateSessionOnPrincipalChange

于 2013-02-07T16:16:42.943 回答