⒈是什么?

  即控制业务系统中一个用户只能有一个Session

⒉解决方案

  1.当这个用户在其它地方登录的时候,把之前的Session失效掉。

 package cn.coreqi.security.config;

 import cn.coreqi.security.Filter.SmsCodeFilter;
import cn.coreqi.security.Filter.ValidateCodeFilter;
import cn.coreqi.security.session.CoreqiExpiredSessionStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired
private AuthenticationSuccessHandler coreqiAuthenticationSuccessHandler; @Autowired
private AuthenticationFailureHandler coreqiAuthenticationFailureHandler; @Autowired
private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig; @Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
} @Override
protected void configure(HttpSecurity http) throws Exception {
ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
validateCodeFilter.setAuthenticationFailureHandler(coreqiAuthenticationFailureHandler); SmsCodeFilter smsCodeFilter = new SmsCodeFilter(); //http.httpBasic() //httpBasic登录 BasicAuthenticationFilter
http.addFilterBefore(smsCodeFilter, UsernamePasswordAuthenticationFilter.class) //加载用户名密码过滤器的前面
.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class) //加载用户名密码过滤器的前面
.formLogin() //表单登录 UsernamePasswordAuthenticationFilter
.loginPage("/coreqi-signIn.html") //指定登录页面
//.loginPage("/authentication/require")
.loginProcessingUrl("/authentication/form") //指定表单提交的地址用于替换UsernamePasswordAuthenticationFilter默认的提交地址
.successHandler(coreqiAuthenticationSuccessHandler) //登录成功以后要用我们自定义的登录成功处理器,不用Spring默认的。
.failureHandler(coreqiAuthenticationFailureHandler) //自己体会把
.and()
.sessionManagement()
.invalidSessionUrl("session/invalid") //session过期后跳转的URL
.maximumSessions(1) //配置最大的Session数量,即同一个用户后面登录所产生的Session之前登录所产生的Session给失效掉
.expiredSessionStrategy(new CoreqiExpiredSessionStrategy())
.and()
.and()
.authorizeRequests() //对授权请求进行配置
.antMatchers("/coreqi-signIn.html","/code/image","/session/invalid").permitAll() //指定登录页面不需要身份认证
.anyRequest().authenticated() //任何请求都需要身份认证
.and().csrf().disable() //禁用CSRF
.apply(smsCodeAuthenticationSecurityConfig);
//FilterSecurityInterceptor 整个SpringSecurity过滤器链的最后一环
}
}
 package cn.coreqi.security.session;

 import org.springframework.security.web.session.SessionInformationExpiredEvent;
import org.springframework.security.web.session.SessionInformationExpiredStrategy; import javax.servlet.ServletException;
import java.io.IOException; public class CoreqiExpiredSessionStrategy implements SessionInformationExpiredStrategy {
@Override
public void onExpiredSessionDetected(SessionInformationExpiredEvent sessionInformationExpiredEvent) throws IOException, ServletException {
sessionInformationExpiredEvent.getResponse().setContentType("application/json;charset=UTF-8");
sessionInformationExpiredEvent.getResponse().getWriter().write("并发登录!");
}
}

  2.当这个用户已经登陆了,禁止在其它地方登录。

 package cn.coreqi.security.config;

 import cn.coreqi.security.Filter.SmsCodeFilter;
import cn.coreqi.security.Filter.ValidateCodeFilter;
import cn.coreqi.security.session.CoreqiExpiredSessionStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired
private AuthenticationSuccessHandler coreqiAuthenticationSuccessHandler; @Autowired
private AuthenticationFailureHandler coreqiAuthenticationFailureHandler; @Autowired
private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig; @Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
} @Override
protected void configure(HttpSecurity http) throws Exception {
ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
validateCodeFilter.setAuthenticationFailureHandler(coreqiAuthenticationFailureHandler); SmsCodeFilter smsCodeFilter = new SmsCodeFilter(); //http.httpBasic() //httpBasic登录 BasicAuthenticationFilter
http.addFilterBefore(smsCodeFilter, UsernamePasswordAuthenticationFilter.class) //加载用户名密码过滤器的前面
.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class) //加载用户名密码过滤器的前面
.formLogin() //表单登录 UsernamePasswordAuthenticationFilter
.loginPage("/coreqi-signIn.html") //指定登录页面
//.loginPage("/authentication/require")
.loginProcessingUrl("/authentication/form") //指定表单提交的地址用于替换UsernamePasswordAuthenticationFilter默认的提交地址
.successHandler(coreqiAuthenticationSuccessHandler) //登录成功以后要用我们自定义的登录成功处理器,不用Spring默认的。
.failureHandler(coreqiAuthenticationFailureHandler) //自己体会把
.and()
.sessionManagement()
.invalidSessionUrl("session/invalid") //session过期后跳转的URL
.maximumSessions(1) //配置最大的Session数量,即同一个用户后面登录所产生的Session之前登录所产生的Session给失效掉
.maxSessionsPreventsLogin(true) //当一个用户的Session数量达到最大数量以后,阻止后面的登陆行为
.expiredSessionStrategy(new CoreqiExpiredSessionStrategy())
.and()
.and()
.authorizeRequests() //对授权请求进行配置
.antMatchers("/coreqi-signIn.html","/code/image","/session/invalid").permitAll() //指定登录页面不需要身份认证
.anyRequest().authenticated() //任何请求都需要身份认证
.and().csrf().disable() //禁用CSRF
.apply(smsCodeAuthenticationSecurityConfig);
//FilterSecurityInterceptor 整个SpringSecurity过滤器链的最后一环
}
}

SpringBoot的Session并发控制的更多相关文章

  1. SpringBoot,Security4, redis共享session,分布式SESSION并发控制,同账号只能登录一次

    由于集成了spring session ,redis 共享session,导致SpringSecurity单节点的session并发控制失效, springSession 号称 无缝整合httpses ...

  2. Spring Boot+Spring Security:获取用户信息和session并发控制

    说明 (1)JDK版本:1.8(2)Spring Boot 2.0.6(3)Spring Security 5.0.9(4)Spring Data JPA 2.0.11.RELEASE(5)hiber ...

  3. SpringBoot 分布式session

    SpringBoot 分布式session实现 1. 什么是分布式session 在集群环境中,不得不考虑的一个问题是用户访问产生的session如何处理.如过不做任何处理,用户将出现频繁俸禄的现象, ...

  4. 从.Net到Java学习第八篇——SpringBoot实现session共享和国际化

    从.Net到Java学习系列目录 SpringBoot Session共享 修改pom.xml添加依赖 <!--spring session--> <dependency> & ...

  5. springboot设置session超时和session监听

    2.0版本以下设置session超时时间 1.  springboot 2.0版本以下配置session超时 1.1 application.properties配置文件: spring.sessio ...

  6. SpringBoot设置Session失效时间

    1 #Session超时时间设置,单位是秒,默认是30分钟 2 server.session.timeout=10 然而并没有什么用,因为SpringBoot在TomcatServletWebServ ...

  7. 二十三、springboot之session共享

    通过redis实现session共享 SpringBoot集成springsession 1.引入依赖(gradle方式) dependencies { compile('org.springfram ...

  8. springboot+spring session+redis+nginx实现session共享和负载均衡

    环境 centos7. jdk1.8.nginx.redis.springboot 1.5.8.RELEASE session共享 添加spring session和redis依赖 <depen ...

  9. springboot处理session生命周期

    在使用springboot开发过程中发现用户登陆后60s后session就自动失效了,需要重新登陆,明明 application.yml  文件里已经配置了 server.session.timeou ...

随机推荐

  1. Centos7安装Mysql5.7方法总结 - 实操手册

    Centos7.x版本下针对Mysql的安装和使用多少跟之前的Centos6之前版本有所不同的,废话就不多赘述了,下面介绍下在centos7.x环境里安装mysql5.7的几种方法:一.yum方式安装 ...

  2. Vue之vue-cli安装与简单调试

    一.安装nodejs https://nodejs.org/en/download/ nodejs简单使用 node -v 查看版本 npm -v 查看对应npm版本 如果npm版本太低小于 4.0 ...

  3. jmeter打开图形化界面时指定代理

    \apache-jmeter-4.0\bin>jmeter -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888 如果不想在每个请求里面指定代理的话可 ...

  4. C#设计模式(8)——外观模式

    1.外观模式介绍 外观模式也被叫做门面模式,这种模式的作用是:隐藏系统的复杂性,并向客户端提供了一个可以访问系统的统一接口,这个统一的接口组合了子系统的多个接口.使用统一的接口使得子系统更容易被访问或 ...

  5. Web API中的Help Page

    一.自动创建带帮助的WebAPI 第一步  创建项目的时候选择WebAPI 如下图所示,生成的项目会自动生成帮助文档 第二步  设置调用XML文档的代码 第三步 设置项目注释XML文档生成目录 项目— ...

  6. 关于js事件执行顺序

    关于js事件执行顺序小技巧 js事件执行顺序是js中一个老生常谈的一个话题, 聊这个话题之前我们先谈谈怎么给页面元素绑定我们需要的事件 1.给页面元素绑定事件 a)直接在元素上面加上需要绑定的事件,如 ...

  7. 分布式配置 SSH 免密登陆

    原地址忘记了,暂且记下 一.准备工作 1) 用客户端工具(ssh client或者putty)连接到linux服务器.在root用户下输入命令 vi /etc/hosts,用vi编辑hosts文件,如 ...

  8. chart.js angular组件封装(ng6)、实战配置、插件编写

    前言 项目需要使用chart.js插件,由于项目是使用angular开发,那么我第一步就是先把chart.js改造成angular组件来使用. 本项目代码都可以在github上下载:项目git地址 a ...

  9. 对空间数据(Shape)重新排序

    打开ArcToolBox,数据管理工具->常规(General)->排序

  10. Mac OS X 启用超级用户 sudo -s 获得系统权限 Mac终端命令

    为了防止误操作破坏系统,用户状态下时没有权限操作系统重要文件, 所以先要取得root权限:“sudo -s” 详见:https://www.jianshu.com/p/138b98e662ed