我试图限制用户多次签名(强制前一个会话过期)。
我查看了有关主题here的文档。我将其设置为非常类似于文档,但用户一次不限于一个会话。我可以使用同一个用户多次登录(在不同的浏览器中)并且有多个并发会话。
以下是我认为安全设置的相关内容。我正在使用自定义UserDetailsService,UserDetails和AuthenticationFilter实现。
<http entry-point-ref="authenticationEntryPoint">
<!-- Make sure everyone can access the login page -->
<intercept-url pattern="/login.do*" filters="none" />
[...]
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter" />
<logout logout-url="/logout" logout-success-url="/login.do" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="sha" />
</authentication-provider>
</authentication-manager>
<beans:bean id="userDetailsService" class="[...]">
<beans:property name="userManager" ref="userManager" />
</beans:bean>
<beans:bean id="authenticationFilter" class="[...]">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="eventPublisher">
<beans:bean
class="org.springframework.security.authentication.DefaultAuthenticationEventPublisher" />
</beans:property>
<beans:property name="filterProcessesUrl" value="/security_check" />
<beans:property name="authenticationFailureHandler">
<beans:bean
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.do?login_error=true" />
</beans:bean>
</beans:property>
<beans:property name="sessionAuthenticationStrategy"
ref="sessionAuthenticationStrategy" />
</beans:bean>
<beans:bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.do" />
</beans:bean>
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/login.do?login_error=true!" />
</beans:bean>
<beans:bean id="sessionAuthenticationStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry"
ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
我还在我的web.xml文件中注册了org.springframework.security.web.session.HttpSessionEventPublisher
作为监听器。
据我所知,我已根据文档对其进行了配置。我不知道为什么这不起作用。它是否与我使用基于表单的登录这一事实有关?或者我上面提到的自定义实现?
答案 0 :(得分:9)
我明白了。如果重新实现UserDetails,则必须为SessionRegistryImpl提供hashCode()方法才能使用。文档中没有提到这一点。
答案 1 :(得分:2)
我知道这已经得到了解答,但是有一个更简单的解决方案,它不需要配置特定的过滤器。您可以在http标记中添加以下XML来配置会话:
<session-management invalid-session-url="/login">
<concurrency-control max-sessions="1" expired-url="/login" />
</session-management>
基于表单的其他登录配置也过于复杂。我在这里写了一篇帖子http://codehustler.org/blog/spring-security-form-login-tutorial/,其中展示了如何正确配置表单登录。