我们正在从Spring Security 2.0迁移到3.1。
在Spring Security 2.0中,配置了并发控制,在配置文件中添加以下行:
<concurrent-session-control max-sessions="1" />
现在,3.1,我们添加了以下内容:
<session-management invalid-session-url="/index.jsf">
<concurrency-control max-sessions="1" />
</session-management>
我们从支持bean进行登录。代码如下:
public String login(){
Authentication authenticationResponseToken = authenticate();
if (authenticationResponseToken != null && authenticationResponseToken.isAuthenticated()) {
return NavigationConstants.PORTAL_REDIRECT_USER;
}
else{
return NavigationConstants.PORTAL_LOGIN + sessionManagedBean.getUrlQuery();
}
}
private Authentication authenticate(){
debug("authenticate");
AuthenticationManager authenticationManager = (AuthenticationManager) UtilidadesFaces.getSpringBean("authManager");
//simple token holder
Authentication authenticationRequestToken = createAuthenticationToken(sessionManagedBean);
Authentication authenticationResponseToken = null;
//authentication action
try {
authenticationResponseToken = authenticationManager.authenticate(authenticationRequestToken);
SecurityContextHolder.getContext().setAuthentication(authenticationResponseToken);
List<GrantedAuthority> authorities = (List<GrantedAuthority>) authenticationResponseToken.getAuthorities();
if(authorities.size() > 0){
this.sessionManagedBean.setRole(authorities.get(0).getAuthority());
}
CustomUser customUser = (CustomUser) authenticationResponseToken.getPrincipal();
this.sessionManagedBean.setIdCl(customUser.getIdCl());
} catch (BadCredentialsException badCredentialsException) {
UtilidadesFaces.addMessage(null, FacesMessage.SEVERITY_ERROR, "login.error.badCredentialsException", this.sessionManagedBean.getActualLanguage());
} catch (AuthenticationServiceException badCredentialsException) {
UtilidadesFaces.addMessage(null, FacesMessage.SEVERITY_ERROR, "login.error.badCredentialsException", this.sessionManagedBean.getActualLanguage());
} catch (LockedException lockedException) {
UtilidadesFaces.addMessage(null, FacesMessage.SEVERITY_ERROR, "login.error.lockedException", this.sessionManagedBean.getActualLanguage());
} catch (DisabledException disabledException) {
UtilidadesFaces.addMessage(null, FacesMessage.SEVERITY_ERROR, "login.error.disabledException", this.sessionManagedBean.getActualLanguage());
}
return authenticationResponseToken;
}
private Authentication createAuthenticationToken(SessionManagedBean sessionManagedBean) {
String username = sessionManagedBean.getUsername() + sessionManagedBean.getIdGuest();
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(username, sessionManagedBean.getPassword());
return usernamePasswordAuthenticationToken;
}
我们已经在实现UserDetails的类中实现了equals()和hashCode()方法。
现在没有并发控制正在运行,一个用户可以多次登录并同时处理所有会话。
任何帮助都将不胜感激。
答案 0 :(得分:1)
我正在使用spring 3.2.1,我刚刚做了以下
// spring will inject ConcurrentSessionControlAuthenticationStrategy by default
@Autowired
SessionAuthenticationStrategy sessionAuthenticationStrategy;
并在我刚刚调用的身份验证方法中
sessionAuthenticationStrategy.onAuthentication(authenticationResponseToken,httpReq,httpResp);
在security.xml文件中
<session-management invalid-session-url="/login.jsp?time=1">
<concurrency-control error-if-maximum-exceeded="false" max-sessions="1" expired-url="/logout"/>
</session-management>
由于所有这些都是默认值,我认为我们不需要设置它。
这对我有用。
答案 1 :(得分:0)
试试这个......根据我的工作
<session-management session-fixation-protection="newSession">
<concurrency-control error-if-maximum-exceeded="true" max-sessions="1" expired-url="/loginexpired" />
</session-management>
答案 2 :(得分:0)
最后我解决了调用SessionAuthenticationStrategy#onAuthentication并添加一些spring安全过滤器的问题。
我的代码:
<http auto-config="false" use-expressions="true">
<session-management session-authentication-strategy-ref="sas" invalid-session-url="/index.jsf" />
......
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
</http>
<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:bean>
<beans:bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/index.jsf" />
</beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
....
并添加sessionAuthenticationStrategy.onAuthentication()...
private Authentication authenticate(){
debug("authenticate");
AuthenticationManager authenticationManager = (AuthenticationManager) UtilidadesFaces.getSpringBean("authManager");
//simple token holder
Authentication authenticationRequestToken = createAuthenticationToken(sessionManagedBean);
Authentication authenticationResponseToken = null;
//authentication action
try {
authenticationResponseToken = authenticationManager.authenticate(authenticationRequestToken);
SecurityContextHolder.getContext().setAuthentication(authenticationResponseToken);
List<GrantedAuthority> authorities = (List<GrantedAuthority>) authenticationResponseToken.getAuthorities();
if(authorities.size() > 0){
this.sessionManagedBean.setRole(authorities.get(0).getAuthority());
}
CustomUser customUser = (CustomUser) authenticationResponseToken.getPrincipal();
this.sessionManagedBean.setIdCl(customUser.getIdCl());
HttpServletRequest httpReq = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse httpResp = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
SessionAuthenticationStrategy sessionAuthenticationStrategy = (SessionAuthenticationStrategy) UtilidadesFaces.getSpringBean("sas");;
sessionAuthenticationStrategy.onAuthentication(authenticationResponseToken, httpReq, httpResp);
} catch (BadCredentialsException badCredentialsException) {
UtilidadesFaces.addMessage(null, FacesMessage.SEVERITY_ERROR, "login.error.badCredentialsException", this.sessionManagedBean.getActualLanguage());
} catch (AuthenticationServiceException badCredentialsException) {
UtilidadesFaces.addMessage(null, FacesMessage.SEVERITY_ERROR, "login.error.badCredentialsException", this.sessionManagedBean.getActualLanguage());
} catch (LockedException lockedException) {
UtilidadesFaces.addMessage(null, FacesMessage.SEVERITY_ERROR, "login.error.lockedException", this.sessionManagedBean.getActualLanguage());
} catch (DisabledException disabledException) {
UtilidadesFaces.addMessage(null, FacesMessage.SEVERITY_ERROR, "login.error.disabledException", this.sessionManagedBean.getActualLanguage());
}
return authenticationResponseToken;
}