我是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;授予权限:内部'
我的理解是安全上下文持有者存储所有用户的详细信息。但在这种情况下,我无法从其他选项卡/浏览器启动应用程序。
听起来像您的自定义身份验证过滤器忽略了URL参数中的更改,可能是因为用户已经过身份验证。此外,你应该删除所有并发会话的东西,直到你可以让他的基本工作正常。 –
感谢您的回应卢克。这里的问题是,当第二个请求被触发时,我的customAuthenticationFilter根本没有被触发。请查看我添加到问题的日志跟踪。 –
@LukeTaylor,这里再补充一点。我们没有适当的登录机制。我们所拥有的是来自URL的独特参考。因此理想情况下,当第二个请求到来时,它与尝试进行身份验证的新用户一样好。但是,安全环境已经被第一个用户的令牌填充了,此刻我很无能。我现在正在尝试SecurityContextPersistenceFilter过滤器。我正朝着正确的方向走吗? –