继续说说spring security之并发控制(Concurrency Control)

定义,作用,说明:

Concurrency Control:并发控制,主要用于避免同一用户多次登录,重复登录以及包括相关的session管理--具体官网---》

先看官网:http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#session-mgmt

官网的并发控制已经说得比较清楚,但是偏偏有人(例如我)重写了(自定义了)验证的方法,导致了失效的问题,至此,一起说说spring security之并发控制配置以及相关编写:

分为三种方式:

基本配置:

web.xml 加入监听

<listener>
  <listener-class>
    org.springframework.security.web.session.HttpSessionEventPublisher
  </listener-class>
</listener>

第一种,入门试(简单配置)没有自定义了spring security验证的

<http>
  ...
  <session-management>
     <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
  </session-management>
</http>

或者

<http>
  ...
  <session-management>
     <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
  </session-management>
</http>

区别在于前者剔除上一个用户,后者第二个不给登录

记住前提:没有自定义验证方法,官网:

If you are using a customized authentication filter for form-based login, then you have to configure concurrent session control support explicitly. More details can be found in the Session Management chapter.

但如果自定义了自定义的UserDetails 则需要重定义equal和hashcode

第二种方法:

打开官网其实已经说得很清楚了。。。。

还不清楚再看来自iteye的网友 http://sb33060418.iteye.com/blog/1953515

第三种方法(我就是用这种。。。)

首先看看我的验证(使用程序的方法去调用,很大限度的自定义了验证)

    public LoginInfo login(@RequestParam(defaultValue="") String username,@RequestParam(defaultValue="") String password,HttpServletRequest request,HttpServletResponse response){
        if(!checkValidateCode(request)){
            return new LoginInfo().failed().msg("验证码错误!");
        }
        username = username.trim();
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
/*        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(CwSysUser.class,"cwSysUser");
        detachedCriteria.add(Restrictions.eq("userNo", username));
        if(cwSysUserService.countUser(detachedCriteria)==0){
            return new LoginInfo().failed().msg("用户名: "+username+" 不存在.");
        }
*/        try {
            Authentication authentication = myAuthenticationManager.authenticate(authRequest); //调用loadUserByUsername
            SecurityContextHolder.getContext().setAuthentication(authentication);
            HttpSession session = request.getSession();
            session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext()); // 这个非常重要,否则验证后将无法登陆
            sas.onAuthentication(authentication, request, response);
            return new LoginInfo().success().msg(authentication.getName());
        }catch (AuthenticationException ex) {
            if(ex.getMessage()==null){
                return new LoginInfo().failed().msg("用户名不存在.");
            }
            return new LoginInfo().failed().msg("用户名或密码错误");
        }
    }
    

说明:

Authentication authentication = myAuthenticationManager.authenticate(authRequest); //这里就是在程序中用
myAuthenticationManager调用了验证信息,基于myAuthenticationManager在下面xml的配置重新写了loadUserByUsername方法
 sas.onAuthentication(authentication, request, response);// 这里就是手动调用了并发控制(在xml做了注入配置)

配置spring-security.xml (配置基本和二差不错,但是少了自定义登录拦截配置)

    <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
        <session-management
            session-authentication-strategy-ref="sas" />
    </http>

    <beans:bean id="concurrencyFilter"
        class="org.springframework.security.web.session.ConcurrentSessionFilter">
        <beans:property name="sessionRegistry" ref="sessionRegistry" />
        <beans:property name="expiredUrl" value="/session-expired.htm" />
    </beans:bean>

    <beans:bean id="sas"
        class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
        <beans:constructor-arg>
            <beans:list>
                <beans:bean
                    class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
                    <beans:constructor-arg ref="sessionRegistry" />
                    <beans:property name="maximumSessions" value="1" />
                </beans:bean>
                <beans:bean
                    class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
                </beans:bean>
                <beans:bean
                    class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
                    <beans:constructor-arg ref="sessionRegistry" />
                </beans:bean>
            </beans:list>
        </beans:constructor-arg>
    </beans:bean>

    <beans:bean id="sessionRegistry"
        class="org.springframework.security.core.session.SessionRegistryImpl" />

    <authentication-manager alias="myAuthenticationManager">
        <authentication-provider user-service-ref="cwSysUserDetailsService">  <!-- 数据库提供者 -->
            <password-encoder hash="md5"></password-encoder>
        </authentication-provider>
    </authentication-manager>

至此,完成。。。。。

非常感谢:stackoverflow和ma4的自问自答,这种精神很想点赞,可惜要登录,要登录就是要FQ,可惜点了半天还没有出来。欲跋千山,涉万水,翻过高墙,穿过荒原,只为跟你说声:谢谢。

http://stackoverflow.com/questions/26041756/concurrency-control-is-not-working

时间: 2024-07-31 07:58:55

继续说说spring security之并发控制(Concurrency Control)的相关文章

Spring Security OAuth2 开发指南。

官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. Spring OAuth2.0 提供者实现原理: Spring OAuth2.0提供者实际上分为: 授权服务 Authorization Service. 资源服务 Resource Service. 虽然这两个提供者有时候可能存在同一个应用程序中,但在Spring Security OAuth中你可以把 他它们各自放在

Spring Security 入门(1-14)Spring Security 开发指南(转)

开发指南:http://www.cnblogs.com/xingxueliao/p/5911292.html Spring OAuth2.0 提供者实现原理: Spring OAuth2.0提供者实际上分为: 授权服务 Authorization Service. 资源服务 Resource Service. 虽然这两个提供者有时候可能存在同一个应用程序中,但在Spring Security OAuth中你可以把 他它们各自放在不同的应用上,而且你可以有多个资源服务,它们共享同一个中央授权服 务

乐观的并发控制(optimistic concurrency control)

ES是分布式的.当document被create,update,或者delete,这个document的新版本就会冗余到cluster的其他node中.ES是异步和并发的,意味着冗余请求也是并行进行的,并且请求到达也是无次序的.因此需要一个方式保证老版本的document不能重写新版本的数据. 如上所述,当我们讨论index,get和delete请求,我们指出每个document都有一个_version号,这个号码随着document的变化而增长.ES使用这个_version保证document

Spring Security应用开发(11) 并发控制之实践

本文分别介绍了四种不同情况下,Spring Security的Session管理和并发控制的不同配置的配置方法,以及所产生的效果. (1)首先编写了session_error.jsp页面,用于展示session相关错误信息. 错误信息通过页面参数id传入. <p>Session Error:${param.id }</p> <p>${SPRING_SECURITY_LAST_EXCEPTION.message}</p> (2)编写相应的SessionCont

数据访问模式:数据并发控制(Data Concurrency Control)

1.数据并发控制(Data Concurrency Control)简介 数据并发控制(Data Concurrency Control)是用来处理在同一时刻对被持久化的业务对象进行多次修改的系统.当多个用户修改业务对象的状态并试图并发地将其持久化到数据库时,需要一种机制来确保一个用户不会对另一个并发用户的事务状态造成负面影响. 有两种形式的并发控制:乐观和悲观.乐观并发控制假设当多个用户对业务对象的状态同时进行修改时不会造成任何问题,也称为最晚修改生效(last change wins).对于

Spring Security应用开发(10) 并发控制之基本介绍

同一个用户使用不同的浏览器登录,将会导致什么结果呢?Spring Security提供了多种选项. <!-- session管理 --> <sec:session-management session-fixation-protection="changeSessionId" session-authentication-error-url="/login/session_error.action?id=max_session_error" inv

CAS 与 Spring Security 3整合配置详解

一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分.用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.用户授权指的是验证某个用户是否有权限执行某个操作.在一个系统中,不同用户所具有的权限是不同的.比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改.一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限. 对于上面提到的两种应用情景,Spring Security 框

Spring Security 3.2.x与Spring 4.0.x的Maven依赖管理

原文链接: Spring Security with Maven原文日期: 2013年04月24日翻译日期: 2014年06月29日翻译人员: 铁锚 1. 概述 本文通过实例为您介绍怎样使用 Maven 管理 Spring Security 和 Spring 的依赖关系.最新的Spring Security公布版本号能够在 Maven Central仓库 中找到. 译者建议訪问MVNRespotory中org.springframework.security链接.本文是 使用Maven管理Spr

Spring Security对Acl的支持

对Acl的支持 目录 1.1           准备工作 1.2           表功能介绍 1.2.1     表acl_sid 1.2.2     表acl_class 1.2.3     表acl_object_identity 1.2.4     表acl_entry 1.3           Acl主要接口 1.4           配置AclService 1.4.1     配置DataSource 1.4.2     配置LookupStrategy 1.4.3