SpringBoot的Session并发控制
⒈是什么?
即控制业务系统中一个用户只能有一个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并发控制的更多相关文章
- SpringBoot,Security4, redis共享session,分布式SESSION并发控制,同账号只能登录一次
由于集成了spring session ,redis 共享session,导致SpringSecurity单节点的session并发控制失效, springSession 号称 无缝整合httpses ...
- 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 ...
- SpringBoot 分布式session
SpringBoot 分布式session实现 1. 什么是分布式session 在集群环境中,不得不考虑的一个问题是用户访问产生的session如何处理.如过不做任何处理,用户将出现频繁俸禄的现象, ...
- 从.Net到Java学习第八篇——SpringBoot实现session共享和国际化
从.Net到Java学习系列目录 SpringBoot Session共享 修改pom.xml添加依赖 <!--spring session--> <dependency> & ...
- springboot设置session超时和session监听
2.0版本以下设置session超时时间 1. springboot 2.0版本以下配置session超时 1.1 application.properties配置文件: spring.sessio ...
- SpringBoot设置Session失效时间
1 #Session超时时间设置,单位是秒,默认是30分钟 2 server.session.timeout=10 然而并没有什么用,因为SpringBoot在TomcatServletWebServ ...
- 二十三、springboot之session共享
通过redis实现session共享 SpringBoot集成springsession 1.引入依赖(gradle方式) dependencies { compile('org.springfram ...
- springboot+spring session+redis+nginx实现session共享和负载均衡
环境 centos7. jdk1.8.nginx.redis.springboot 1.5.8.RELEASE session共享 添加spring session和redis依赖 <depen ...
- springboot处理session生命周期
在使用springboot开发过程中发现用户登陆后60s后session就自动失效了,需要重新登陆,明明 application.yml 文件里已经配置了 server.session.timeou ...
随机推荐
- python自动化开发-[第一天]-练习题
1.使用while循环输入 1 2 3 4 5 6 8 9 10 i = 1 while i < 11: if i == 7: i += 1 continue print (i) i += 1 ...
- C++回顾day02---<引用>---待补充
一:引用概念---引用就是为一个变量起一个别名 每个变量都是指向一块内存空间的标识,引用就是重新设置一个标识,但是这个标识还是指向同一个内存空间 和指针类似(其实引用本质就是使用了一个常指针 cons ...
- JAVA核心技术I---JAVA基础知识(对象与类)
一:规范 将每一个类存在一个单独的源文件中 Employee.java public class Employee { private int age; private float salay; pr ...
- C#设计模式(5)——建造者模式
1.建造者模式介绍 在软件开发中,有时我们要创建一个复杂的对象,这个对象由几个子部件按一定的步骤组合而成,这时候我们就可以使用建造者模式了.说到建造者我们首先想到的是盖房子,盖房子简单的说有三个步骤: ...
- mysq存储金额的数值类型选择
在之前得项目中用到了double,计算之后有很长得小数位,需要用算法去除,非常麻烦,以后推荐使用:decimal 这个是专门处理金额值的,Java 类型对应BigDecimal
- ssh 跳板机部署
1.首先创建存放日志的文件夹并开放读写权限 mkdir /var/log/jump/ chmod -R 777 /var/log/jump/ 2.将原有ssh程序修改为另外 ...
- 微信小程序ext_json示例
{ "template_id": 0, "ext_json": "{\"extEnable\": true, \"ext ...
- 使用模拟Table解决span重叠问题
<div id="test"> <div > <span>adfafadsfadfa</span> <span style=& ...
- error.c
#include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> ...
- 三十九、Linux 线程——线程的同步和互斥
39.1 概念 线程同步 是一个宏观概念,在微观上包含线程的相互排斥和线程先后执行的约束问题 解决同步方式 条件变量 线程信号量 线程互斥 线程执行的相互排斥 解决互斥的方式 互斥锁 读写锁 线程信号 ...