我有一个基于spring框架的应用程序。 此应用程序允许每个用户2个多个会话。
<bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<property name="sessionRegistry" ref="sessionRegistry" />
<property name="expiredUrl" value="/faces/pages/templates/error.xhtml" />
</bean>
<bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<bean id="sas"
class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<constructor-arg>
<list>
<bean
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<constructor-arg ref="sessionRegistry" />
<property name="maximumSessions" value="2" />
<property name="exceptionIfMaximumExceeded" value="true" />
</bean>
<bean
class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
</bean>
<bean
class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<constructor-arg ref="sessionRegistry" />
</bean>
</list>
</constructor-arg>
</bean>
我需要在第二次会话登录时杀死第一个会话。
我尝试使用expireNow方法,但是2个会话保持活动状态。
authenticate = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(username, password));
if (authenticate.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(authenticate);
HttpServletRequest httpReq = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext()
.getRequest();
HttpServletResponse httpResp = (HttpServletResponse) FacesContext.getCurrentInstance()
.getExternalContext().getResponse();
sessionAuthenticationStrategy.onAuthentication(authenticate, httpReq, httpResp);
final Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
final org.springframework.security.core.userdetails.User user = new org.springframework.security.core.userdetails.User(
username, password, grantedAuthorities);
List<SessionInformation> sessions = sessionRegistry.getAllSessions(user, false);
if (sessions.size() > 1) {
sessionRegistry.getSessionInformation(sessions.get(0).getSessionId()).expireNow();
sessionRegistry.removeSessionInformation(sessions.get(0).getSessionId());
}
我怎样才能做到这一点!
谢谢。
答案 0 :(得分:0)
请见Destroy a session of another user in spring。我希望这有帮助。特别在<session-management ...>
部分中查找有关<http>
的评论。
答案 1 :(得分:0)
您可以尝试在登录代码之前添加如下内容。
这应该使尚未过期的特定用户( authentication.getPrincipal())的会话过期,然后将其从Spring Security会话注册表中删除:
// expire and remove the user's sessions from sessionRegistry
List<Object> principals = sessionRegistry.getAllPrincipals();
for (Object principal : principals) {
List<SessionInformation> sessions = sessionRegistry.getAllSessions(principal, true);
for (SessionInformation sessionInfo : sessions) {
if (authentication.getPrincipal().equals(sessionInfo.getPrincipal())) {
if (!sessionInfo.isExpired()) sessionInfo.expireNow();
sessionRegistry.removeSessionInformation(sessionInfo.getSessionId());
}
}
}