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 ...
随机推荐
- makefile解析:一些常用函数
#======================================================================= #指定目标文件名,makefile中的变量直接使用不用 ...
- CodeForces1065F 树形dp
http://codeforces.com/problemset/problem/1065/F 你有一棵带有n个结点的树,根是结点1.有一个标记,最初在根结点处.你可以将标记移动到其他结点处.假设标记 ...
- SpringMVC简单项目配置
一.首先,SpringMVC框架使用分层开发,分层是为了实现“高内聚,低耦合”.采用“分而治之”的思想,把问题划分开来各个解决,易于控制,延展和分配资源,最重要的是有利于后期项目维护.MVC是指Mod ...
- python爬虫之Cookie
由于http协议是无状态协议(假如登录成功,当访问该网站的其他网页时,登录状态消失),此时,需要将会话信息保存起来,通过cookie或者session的方式 cookie 将所有的回话信息保存在客户端 ...
- python mysql 视图 触发器 事物 存储过程 用户授权 数据备份还原
###################总结########### 视图是一个虚拟表(非真实存在) 是跑在内存中的表,真实表是在硬盘上的表 使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去 ...
- Linux 内核源代码根目录
1. arch :与体系结构相关的文件 2. block: 包含块存储设备IO调度算法的实现 3. cryrto: 密码操作有关 4. Documention: 内核中各个子系 ...
- nginx 前端POST请求405问题解决与排查过程
问题描述 在请求时,f12提示POST请求报错405 环境描述 nginx转发至后端nginx,后端nginx转发至后端golang api接口 解决步骤 根据网上方法排查,发现80%以上无非就是以下 ...
- Java高并发秒杀API之web层
第1章 设计Restful接口 1.1前端交互流程设计 1.2 学习Restful接口设计 什么是Restful?它就是一种优雅的URI表述方式,用来设计我们资源的访问URL.通过这个URL的设计,我 ...
- Silverlight 样式的灵活使用
众所周知,Silverlight将界面设计与代码实现分开.即便如此,如果不能灵活地运用样式Style,开发的效率依然会比较低.比如,针对类似的TextBlock,你可能需要反复地在设计器xaml中复制 ...
- 用Google Brain的机器学习项目:Magenta,教神经网络学抖音小姐姐作曲。
先上我们要学习的小姐姐 的美照.. 一.配置环境 1.自己配置环境:python,tensorflow,bazel(编译),java.然后下载magenta(https://github.com/te ...