首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并发控制不起作用

并发控制不起作用
EN

Stack Overflow用户
提问于 2014-09-25 22:56:52
回答 3查看 3.1K关注 0票数 2

我们正在从Spring Security 2.0迁移到3.1。

在Spring Security2.0中,配置了并发控制,在配置文件中添加了以下行:

代码语言:javascript
复制
<concurrent-session-control max-sessions="1" />

现在,在3.1版本中,我们添加了以下内容:

代码语言:javascript
复制
<session-management invalid-session-url="/index.jsf">
    <concurrency-control max-sessions="1" />
</session-management>

我们从一个支持bean进行登录。代码如下:

代码语言:javascript
复制
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()方法。

现在没有并发控制在工作,一个用户可以多次登录并同时使用所有会话。

任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2014-12-03 18:11:04

我使用的是spring 3.2.1,我只做了以下几件事

// spring will inject ConcurrentSessionControlAuthenticationStrategy by default @Autowired SessionAuthenticationStrategy sessionAuthenticationStrategy;

在您的身份验证方法中,我刚刚调用了

sessionAuthenticationStrategy.onAuthentication(authenticationResponseToken,httpReq,httpResp);

并在security.xml文件中

代码语言:javascript
复制
<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
EN

Stack Overflow用户

发布于 2014-09-26 18:07:50

试用this..according告诉我它的工作原理

代码语言:javascript
复制
<session-management session-fixation-protection="newSession">
            <concurrency-control error-if-maximum-exceeded="true" max-sessions="1" expired-url="/loginexpired" />
         </session-management>
票数 0
EN

Stack Overflow用户

发布于 2014-09-30 18:39:14

最后,我调用SessionAuthenticationStrategy#onAuthentication并添加了一些spring安全过滤器,从而解决了这个问题。

我的代码:

代码语言:javascript
复制
<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()...

代码语言:javascript
复制
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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26041756

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档