2536-springsecurity系列--关于session管理1
版本信息
<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的更多相关文章
- ABP(现代ASP.NET样板开发框架)系列之7、ABP Session管理
		
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之7.ABP Session管理 ABP是“ASP.NET Boilerplate Project (ASP.NET ...
 - 【SpringSecurity系列2】基于SpringSecurity实现前后端分离无状态Rest API的权限控制原理分析
		
源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...
 - Hibernate 系列 05 - Session 类
		
引导目录: Hibernate 系列教程 目录 前言: Session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库的存取都与Session息息相关. 就如同在编写JDBC时需要关 ...
 - SAP接口编程 之 JCo3.0系列(04) : 会话管理
		
在SAP接口编程之 NCo3.0系列(06) : 会话管理 这篇文章中,对会话管理的相关知识点已经说得很详细了,请参考.现在用JCo3.0来实现. 1. JCoContext 如果SAP中多个函数需要 ...
 - ASP.NET Core中的OWASP Top 10 十大风险-失效的访问控制与Session管理
		
不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...
 - Shiro权限管理框架(四):深入分析Shiro中的Session管理
		
其实关于Shiro的一些学习笔记很早就该写了,因为懒癌和拖延症晚期一直没有落实,直到今天公司的一个项目碰到了在集群环境的单点登录频繁掉线的问题,为了解决这个问题,Shiro相关的文档和教程没少翻.最后 ...
 - 【SpringSecurity系列1】基于SpringSecurity实现前后端分离无状态Rest API的权限控制
		
源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...
 - Nhibernate的Session管理
		
参考:http://www.cnblogs.com/renrenqq/archive/2006/08/04/467688.html 但这个方法还不能解决Session缓存问题,由于创建Session需 ...
 - Openfire的启动过程与session管理
		
说明 本文源码基于Openfire4.0.2. Openfire的启动 Openfire的启动过程非常的简单,通过一个入口初始化lib目录下的openfire.jar包,并启动一个 ...
 
随机推荐
- 为什么说 Gradle 是 Android 进阶绕不去的坎 —— Gradle 系列(1)
			
请点赞,你的点赞对我意义重大,满足下我的虚荣心. Hi,我是小彭.本文已收录到 GitHub · Android-NoteBook 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,欢迎 ...
 - 认识并安装WSL
			
认识并安装WSL(基于Windows的Linux子系统) 什么是WSL WSL(Windows Subsystem for Linux),这是在windows平台运行的linux子系统.也就是说可是不 ...
 - 好客租房9-jsx的学习目标
			
1能够知道什么是jsx 2能够使用jsx创建react元素 3能够在jsx使用javascript表达式 4能够使用jsx的条件渲染和列表渲染 5能够给jsx添加样式 jsx的基本使用 jsx中使用j ...
 - 词云图value传递数据不显示(已解决)
			
问题描述: 今天在做词云图时,虽然词云图能够展现出来,但是后台传递过来的数据(每个词出现的次数)却不显示. 错误原因: 错误的将tooltip写在了series内部,如图: 解决方案: 将toolti ...
 - CF Divan and Kostomuksha
			
题意:NKOJ CF 思路:首先发现贪心不了.因此dp.然后这题需要维护的就\(g_i\)和\(sum{g_i}\) 状态:\(dp[i]\): 当前最后一个为\(g_i\)的最大值 \(dp[i]= ...
 - Python工程:ImportError: attempted relative import with no known parent package
			
Python工程:ImportError: attempted relative import with no known parent package 解决方法: 1.对每个目录创建的时候都选择创建 ...
 - net core天马行空系列-微服务篇:全声明式http客户端feign快速接入微服务中心nacos
			
1.前言 hi,大家好,我是三合,距离上一篇博客已经过去了整整两年,这两年里,博主通关了<人生>这个游戏里的两大关卡,买房和结婚.最近闲了下来,那么当然要继续写博客了,今天这篇博客的主要内 ...
 - Myers差分算法的理解、实现、可视化
			
作者:Oto_G QQ: 421739728 目录 简介 基础 差异的描述 好的差异比较 算法介绍 名词解释 两个定理 绘制编辑图 感谢 简介 本文章对Myers差分算法(Myers Diff Alg ...
 - 2020 CSP-J 初赛游记
			
估分 预估 85 分,一是怕选错,而是最后真的错了一些 考点 排列组合:论临时抱佛脚的作用 靠前看了一下捆绑法和插板法,果然考了. 2.算法常识,和复杂度分析 冒泡排序最小交换次数 = n-1 , G ...
 - ExtJS 布局-Border 布局(Border layout)
			
更新记录: 2022年6月11日 发布. 2022年6月1日 开始. 1.说明 边框布局允许根据区域(如中心.北部.南部.西部和东部)指定子部件的位置.还可以调整子组件的大小和折叠. 2.设置布局方法 ...