版本信息


<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>1.5.14.RELEASE</version>
<!--实际里面spring-security-web的版本是4.2.7-->
</dependency>

在ss中基本的session管理

  • session无效处理
  • session过期处理
  • 并发登录处理
  • 限制同一用户重复登录和顶号

// 配置session相关
// CustomSecurityProperties是自定义的常量参数类
private void configSession(HttpSecurity http) throws Exception {
http.sessionManagement()
.invalidSessionStrategy(invalidSessionStrategy) //session无效处理策略
.invalidSessionUrl(CustomSecurityProperties.invalidSessionUrl)
.maximumSessions(1) //同一用户最大session数
.maxSessionsPreventsLogin(false) //达到最大数禁止登录(预防并发登录)
.expiredSessionStrategy(sessionInformationExpiredStrategy) //session过期处理策略
.expiredUrl(CustomSecurityProperties.expiredSessionUrl);
}

并发登录处理

例如用户在两台电脑上登录,并在两台电脑上办公,可设置maximumSessions值为2,这样springsecurity在管理session时会对该用户保持两个有效的session。

限制同一用户重复登录和顶号

例如要求用户最多只能在一台电脑上登录,并且另一台电脑登录会顶掉之前的登录信息。

maximumSessions设置为1

maxSessionsPreventsLogin设置为false

例如要求用户最多只能在一台电脑上登录,并且另一台电脑登录会提示不可重复登录。

maximumSessions设置为1

maxSessionsPreventsLogin设置为true

session无效处理和session过期处理

简单的处理,只是进行url跳转,配置invalidSessionUrl和expiredUrl两个参数即可。

如果需要记录session无效或过期时的用户信息、日志等,需要自定义实现类InvalidSessionStrategy和SessionInformationExpiredStrategy

自定义处理

自定义三个类
AbstractSessionStrategy
CustomExpiredSessionStrategy
CustomInvalidSessionStrategy

在config类中进行配置

    /**
* 配置sec的session失效策略
* 配置给sessionManagement
*/
@Bean
@ConditionalOnMissingBean(InvalidSessionStrategy.class)
public InvalidSessionStrategy invalidSessionStrategy() {
return new CustomInvalidSessionStrategy(CustomSecurityProperties.invalidSessionUrl);
} /**
* 配置sec的session过期策略
* 配置给sessionManagement
*/
@Bean
@ConditionalOnMissingBean(SessionInformationExpiredStrategy.class)
public SessionInformationExpiredStrategy sessionInformationExpiredStrategy() {
return new CustomExpiredSessionStrategy(CustomSecurityProperties.invalidSessionUrl);
}

三个实现类的代码:

AbstractSessionStrategy


import com.company.testss12.support.RetVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.Assert; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; /**
* @author starmoon1994
*/
public class AbstractSessionStrategy { private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* 跳转的url
*/
private String destinationUrl;
/**
* 重定向策略
*/
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
/**
* 跳转前是否创建新的session
*/
private boolean createNewSession = true; private ObjectMapper objectMapper = new ObjectMapper(); /**
*/
public AbstractSessionStrategy(String invalidSessionUrl) {
Assert.isTrue(UrlUtils.isValidRedirectUrl(invalidSessionUrl), "url must start with '/' or with 'http(s)'");
this.destinationUrl = invalidSessionUrl;
} protected void onSessionInvalid(HttpServletRequest request, HttpServletResponse response) throws IOException { logger.info("onSessionInvalid IP:{} URI:{}", request.getRemoteHost(), request.getRequestURI()); if (createNewSession) {
request.getSession();
} String sourceUrl = request.getRequestURI();
String targetUrl; if (StringUtils.endsWithIgnoreCase(sourceUrl, ".html")) {
targetUrl = destinationUrl;//+".html";
logger.info("session失效,跳转到" + targetUrl);
redirectStrategy.sendRedirect(request, response, targetUrl);
} else {
String message = "session已失效,请重新登录";
if (isConcurrency()) {
message = message + ",有可能是并发登录导致的";
}
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setContentType("application/json;charset=UTF-8"); RetVO retVO = new RetVO();
retVO.setMsg(message);
response.getWriter().write(objectMapper.writeValueAsString(retVO));
} } /**
* session失效是否是并发导致的
*/
protected boolean isConcurrency() {
return false;
} /**
* Determines whether a new session should be created before redirecting (to
* avoid possible looping issues where the same session ID is sent with the
* redirected request). Alternatively, ensure that the configured URL does
* not pass through the {@code SessionManagementFilter}.
*
* @param createNewSession defaults to {@code true}.
*/
public void setCreateNewSession(boolean createNewSession) {
this.createNewSession = createNewSession;
} }

CustomExpiredSessionStrategy


import org.springframework.security.web.session.SessionInformationExpiredEvent;
import org.springframework.security.web.session.SessionInformationExpiredStrategy; import java.io.IOException; /**
* session失效策略
*/
public class CustomExpiredSessionStrategy extends AbstractSessionStrategy implements SessionInformationExpiredStrategy { public CustomExpiredSessionStrategy(String invalidSessionUrl) {
super(invalidSessionUrl);
} @Override
public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException {
onSessionInvalid(event.getRequest(), event.getResponse());
} @Override
protected boolean isConcurrency() {
return true;
} }

CustomInvalidSessionStrategy


import org.springframework.security.web.session.InvalidSessionStrategy; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; /**
* @author starmoon1994
*/
public class CustomInvalidSessionStrategy extends AbstractSessionStrategy implements InvalidSessionStrategy { public CustomInvalidSessionStrategy(String invalidSessionUrl) {
super(invalidSessionUrl);
} @Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
throws IOException {
onSessionInvalid(request, response);
} }

完整项目工程参考

https://github.com/starmoon1994/springsecurity-collection

2536-springsecurity系列--关于session管理1的更多相关文章

  1. ABP(现代ASP.NET样板开发框架)系列之7、ABP Session管理

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之7.ABP Session管理 ABP是“ASP.NET Boilerplate Project (ASP.NET ...

  2. 【SpringSecurity系列2】基于SpringSecurity实现前后端分离无状态Rest API的权限控制原理分析

    源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...

  3. Hibernate 系列 05 - Session 类

    引导目录: Hibernate 系列教程 目录 前言: Session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库的存取都与Session息息相关. 就如同在编写JDBC时需要关 ...

  4. SAP接口编程 之 JCo3.0系列(04) : 会话管理

    在SAP接口编程之 NCo3.0系列(06) : 会话管理 这篇文章中,对会话管理的相关知识点已经说得很详细了,请参考.现在用JCo3.0来实现. 1. JCoContext 如果SAP中多个函数需要 ...

  5. ASP.NET Core中的OWASP Top 10 十大风险-失效的访问控制与Session管理

    不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...

  6. Shiro权限管理框架(四):深入分析Shiro中的Session管理

    其实关于Shiro的一些学习笔记很早就该写了,因为懒癌和拖延症晚期一直没有落实,直到今天公司的一个项目碰到了在集群环境的单点登录频繁掉线的问题,为了解决这个问题,Shiro相关的文档和教程没少翻.最后 ...

  7. 【SpringSecurity系列1】基于SpringSecurity实现前后端分离无状态Rest API的权限控制

    源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...

  8. Nhibernate的Session管理

    参考:http://www.cnblogs.com/renrenqq/archive/2006/08/04/467688.html 但这个方法还不能解决Session缓存问题,由于创建Session需 ...

  9. Openfire的启动过程与session管理

    说明   本文源码基于Openfire4.0.2.   Openfire的启动       Openfire的启动过程非常的简单,通过一个入口初始化lib目录下的openfire.jar包,并启动一个 ...

随机推荐

  1. python入门基础知识三(列表和元组)

    列表(list)的操作 1. 形式 var = ['char1','char2','char3',...] var = [value1,value2,value3,...] 2. 列表的增删改查 查: ...

  2. 陈胡:Apache SeaTunnel实现 非CDC数据抽取实践

    导读: 随着全球数据量的不断增长,越来越多的业务需要支撑高并发.高可用.可扩展.以及海量的数据存储,在这种情况下,适应各种场景的数据存储技术也不断的产生和发展.与此同时,各种数据库之间的同步与转化的需 ...

  3. Vue2手写源码---响应式数据的变化

    响应式数据变化 数据发生变化后,我们可以监听到这个数据的变化 (每一步后面的括号是表示在那个模块进行的操作) 手写简单的响应式数据的实现(对象属性劫持.深度属性劫持.数组函数劫持).模板转成 ast ...

  4. Fast-Rcnn学习笔记

    Fast-Rcnn学习笔记 paper code Fast-RCNN总览 step1:图片先放进卷积层 step2:再卷积层的特征图谱上回映射出对应的感兴趣区域 step3:集过一层ROI Pooli ...

  5. Mac 睡眠唤醒 不睡眠 问题

    问题 之前一直有夜晚睡觉前电脑关机的习惯,主要是想着电脑也跟人一样️要休息.然后最近想着自己 Mac 干脆每天睡眠算了,省得每天开关机麻烦,所以就最近这段时间每次夜晚睡觉前主动去点了电脑的 「Slee ...

  6. 解决python无法打开谷歌浏览器问题

    python+selenium 打开浏览器网页时可能会出现两种情况, 一.python 初次打开浏览器未进行安装浏览器控制插件, 二.python 能打开浏览器的情况下,突然有一天发现无法打开并报错新 ...

  7. CentOS8安装mysql8.0具体步骤

    操作系统:CentOS Linux release 8.0及以上 Mysql版本:Mysql 8.0.22 x86_64 (MySQL Community Server - GPL) Mysql8下载 ...

  8. JavaScript中的??和?.和??=操作符

    JS中两种不常使用但挺实用的操作符:??和?. 一起来了解并学会使用它们吧: 空值合并操作符:?? 只有当操作符左侧为null或undefined时才会返回操作符右侧的值,否则返回左侧的值. eg: ...

  9. 5G的发布加快了智慧城市/三维物联网等行业的发展

    最近很多人发现自己的5G手机突然没了5G信号,难道是美国搞的鬼? 不不不,这其实是因为5G的NSA基站被撤站了,官方已经做了部署,要大力推进SA网络建设.所以之前支持NSA模式的5G手机,现在都成了4 ...

  10. 【Java面试】Kafka 怎么避免重复消费

    Hi,大家好,我是Mic 一个工作5年的粉丝找到我. 他说: "Mic老师,你要是能回答出这个问题,我就佩服你" 我当场就懵了,现在打赌都这么随意了吗? 我问他问题是什么,他说&q ...