并发控制不起作用

时间:2014-09-25 14:56:52

标签: spring-security

我们正在从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()方法。

现在没有并发控制正在运行,一个用户可以多次登录并同时处理所有会话。

任何帮助都将不胜感激。

3 个答案:

答案 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;
}