2013-02-07 52 views
3

我是Spring Security的新手。我需要做一个基于URL的身份验证,其中用户需要根据唯一的参考进行身份验证,该参考每次都会作为URL中的参数发送。我会将这个引用传递给一个webservice,获取所需的数据,然后对用户进行身份验证(并设置角色)。认证&授权部分工作正常。但是,当我尝试再次访问应用程序(现在在URL中使用不同的引用)时,它会显示“SecurityContextHolder未填充匿名标记,因为它已经包含...”,并且它显示了先前的请求。我试过使用 SecurityContextHolder.getContext()。setAuthentication(null)和SecurityContextHolder.clearContext()来清除安全上下文。Spring Security中的会话管理

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

下面是我的web.xml(只把春来安全部分):

<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> 

弹簧security.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年2月7日17:27:38834 DEBUG [HTTP-8081-2] [org.springframework.security.web.context.HttpSessionSecurityContextRepository.readSecurityContextFromSession(127)] - 目前没有HttpSession 2013-02-07 17:27:38,834 DEBUG [http-8081-2] [org.springframework.security.web.context.HttpSessionSecurityContextRepository.loadContext(85)] - 没有SecurityContext从HttpSession中可用:空值。一个新的将被创建。

对于第二个请求(请注意,在安全上下文的细节是与第一请求的):

2013年2月7日17:27:54272 DEBUG [HTTP-8081-2] [有机.springframework.security.web.context.HttpSessionSecurityContextRepository.readSecurityContextFromSession(158)] - 从SPRING_SECURITY_CONTEXT获得有效的SecurityContext:'[email protected]17293c:身份验证:org.springframework.security.web.authentication .preauth.PreAuthenticatedAuthenticationToken @ 1017293c:Principal:[email protected]:用户名:Internal @ 5581e6e1-7e61-41bb-9257-b3c1acb96519;密码保护];启用:true; AccountNonExpired:true; credentialsNonExpired:true; AccountNonLocked:true;授予权限:内部;证书:[PROTECTED];已验证:true;详细信息:org.sprin[email protected]ffffc434:RemoteIpAddress:10.188.182.107; SessionId:null;授予权限:内部'

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

+0

听起来像您的自定义身份验证过滤器忽略了URL参数中的更改,可能是因为用户已经过身份验证。此外,你应该删除所有并发会话的东西,直到你可以让他的基本工作正常。 –

+0

感谢您的回应卢克。这里的问题是,当第二个请求被触发时,我的customAuthenticationFilter根本没有被触发。请查看我添加到问题的日志跟踪。 –

+0

@LukeTaylor,这里再补充一点。我们没有适当的登录机制。我们所拥有的是来自URL的独特参考。因此理想情况下,当第二个请求到来时,它与尝试进行身份验证的新用户一样好。但是,安全环境已经被第一个用户的令牌填充了,此刻我很无能。我现在正在尝试SecurityContextPersistenceFilter过滤器。我正朝着正确的方向走吗? –

回答

1

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

1

如果您的CustomAuthenticationFilter正在延伸AbstractPreAuthenticatedProcessingFilter,以下2个属性可能会给您一个洞察。 1。checkForPrincipalChanges 2. invalidateSessionOnPrincipalChange