Spring Security系列教程之会话管理处理会话过期问题

目录
  • 前言
  • 一. 会话过期
    • 1. 会话过期概念
    • 2. Session的超时时间
    • 3. 会话过期时的处理策略
  • 二. 会话过期时的处理策略(一)
    • 1. 配置会话过期时间
    • 2. 定义测试接口
    • 3. 配置跳转到某个URL
    • 4. 启动测试
  • 三. 会话过期时的处理策略(二)
    • 1. 自定义MyInvalSessionStrategy类
    • 2. 配置自定义过期策略

前言

在上一章节中,一一哥 给各位讲解了HTTP协议、会话、URL重新、会话固定攻击等概念,并且实现了对会话固定攻击的防御拦截。

在Spring Security中,其实除了可以对会话固定攻击进行拦截之外,还可以对会话过期进行处理,也就是会话可能会过期,过期了该怎么处理。接下来请各位跟着 壹哥 继续学习,看看会话过期时到底怎么处理的吧。

一. 会话过期

1. 会话过期概念

在处理会话过期之前,我们首先得知道啥是会话过期。

所谓的会话过期,是指当用户登录网站后,较长一段时间没有与服务器进行交互,将会导致服务器上的用户会话数据(即session)被销毁。此时,当用户再次操作网页时,如果服务器进行了session校验,那么浏览器将会提醒用户session超时,导致这个问题的关键词有两个:一个是「长时间」,一个是「未操作」

2. Session的超时时间

既然会话会过期,就得有个过期时间,默认情况下,Session的过期时间是30分钟,当然我们可以在yml配置文件手动修改会话的过期时间。

server:
  servlet:
    session:
      #会话过期时间默认是30m过期,最少为1分钟
      timeout: 60s

另外会话的过期时间最少为1分钟,即便我们设置为小于60秒,也会被修正为1分钟,在Spring Boot的TomcatServletWebServerFactory类中,对此有默认实现,源码如下:

private long getSessionTimeoutInMinutes() {
	Duration sessionTimeout = getSession().getTimeout();
	if (isZeroOrLess(sessionTimeout)) {
		return 0;
	}
	return Math.max(sessionTimeout.toMinutes(), 1);
}

private boolean isZeroOrLess(Duration sessionTimeout) {
	return sessionTimeout == null || sessionTimeout.isNegative() || sessionTimeout.isZero();
}

3. 会话过期时的处理策略

你可能会问,万一会话过期了怎么办呢?别担心!

默认情况下,在会话过期时,Spring Security为我们提供了2种处理策略:

跳转到某个指定的URL;

自定义过期策略。

二. 会话过期时的处理策略(一)

在上面的章节中,我给各位介绍了在会话过期时,Spring Security给我们提供了2种处理策略,我们先学习第一种处理策略,即当会话过期时跳转到某个指定的URL,接下来请看代码实现。

1. 配置会话过期时间

为了方便验证测试,我们先把会话的过期时间设置为60秒,这样会话在很短时间内就可以过期。

server:
  servlet:
    session:
      #会话过期时间默认是30m过期,最少为1分钟
      timeout: 60s

2. 定义测试接口

接下来我们定义几个测试接口,并且定义一个用来处理会话过期的接口“/session/inval”。

@RestController
public class UserController {

    @GetMapping("/user/hello")
    public String helloUser() {

        return "hello, user";
    }

    @GetMapping("/admin/hello")
    public String helloAdmin() {

        return "hello, admin";
    }

    @GetMapping("/app/hello")
    public String helloApp() {

        return "hello, app";
    }

    @RequestMapping("/logout")
    public void logout(HttpSession session){
        session.invalidate();
        System.out.println("logout执行了...");
    }

    //定义一个会话过期后要跳转到的接口
    @GetMapping("/session/invalid")
    public String invalid(){

        return "会话过期invalid...";
    }

}

3. 配置跳转到某个URL

我们还是在之前的SecurityConfig类中,进行会话过期效果的配置实现,主要是利用invalSessionUrl()方法来实现。

@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**")
                .hasRole("ADMIN")
                .antMatchers("/user/**")
                .hasRole("USER")
                .antMatchers("/app/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf()
                .disable()
                .formLogin()
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                //注销成功,重定向到该路径下
                .logoutSuccessUrl("/login")
                //使得session失效
                .invalidateHttpSession(true)
                //清除认证信息
                .clearAuthentication(true)
                .and()
                //进行会话管理
                .sessionManagement()
                .sessionFixation()
                //设置会话固定防御策略
                .migrateSession()
                //配置会话过期策略
                .invalidSessionUrl("/session/invalid");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {

        return NoOpPasswordEncoder.getInstance();
    }

}

4. 启动测试

我们把项目重启,然后访问/user/hello接口,在我们登陆认证成功后就可以正常访问/user/hello接口。

这时候如果我们把当前窗口页面关闭,经过60秒后,会话就会过期,等再次访问/user/hello接口,就可以看到如下效果,即跳转到了我们指定的会话过期界面。

三. 会话过期时的处理策略(二)

我在上面说了,会话过期之后的处理策略,除了上面跳转到指定的URL方案之外,我们还可以自定义会话过期策略,其代码如下。

1. 自定义MyInvalSessionStrategy类

我们创建一个MyInvalSessionStrategy类,实现InvalSessionStrategy接口,在这里进行会话过期时的处理逻辑。

//我们先定义一个处理会话过期的策略类
public class MyInvalidSessionStrategy implements InvalidSessionStrategy {

    @Override
    public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write("session无效");
    }

}

2. 配置自定义过期策略

接下来我们把上面定义的MyInvalSessionStrategy类,通过invalSessionStrategy()方法,设置自定义的会话过期策略。

//然后在配置文件中关联处理会话过期策略
@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**")
                .hasRole("ADMIN")
                .antMatchers("/user/**")
                .hasRole("USER")
                .antMatchers("/app/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf()
                .disable()
                .formLogin()
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                //注销成功,重定向到该路径下
                .logoutSuccessUrl("/login")
                //使得session失效
                .invalidateHttpSession(true)
                //清除认证信息
                .clearAuthentication(true)
                .and()
                //进行会话管理
                .sessionManagement()
                .sessionFixation()
                //设置会话固定防御策略
                .migrateSession()
                //配置会话过期策略
                //.invalidSessionUrl("/session/invalid")
                //设置会话过期策略
                .invalidSessionStrategy(new MyInvalidSessionStrategy());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {

        return NoOpPasswordEncoder.getInstance();
    }

}

至此,壹哥就带各位实现了在会话过期时的代码处理方案了,你学会了吗?

到此这篇关于Spring Security系列教程之会话管理处理会话过期问题的文章就介绍到这了,更多相关Spring Security会话过期内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring security实现权限管理示例

    Spring security实现权限管理示例,具体如下: 1.配置文件 1.POM.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.o

  • java中自定义Spring Security权限控制管理示例(实战篇)

    背景描述 项目中需要做细粒的权限控制,细微至url + httpmethod (满足restful,例如: https://.../xxx/users/1, 某些角色只能查看(HTTP GET), 而无权进行增改删(POST, PUT, DELETE)). 表设计 为避嫌,只列出要用到的关键字段,其余敬请自行脑补. 1.admin_user 管理员用户表, 关键字段( id, role_id ). 2.t_role 角色表, 关键字段( id, privilege_id ). 3.t_privi

  • 使用Spring Security控制会话的方法

    1.概述 在本文中,我们将说明Spring Security如何允许我们控制HTTP会话.此控件的范围从会话超时到启用并发会话和其他高级安全配置. 2.会话何时创建? 我们可以准确控制会话何时创建以及Spring Security如何与之交互: •always - 如果一个会话尚不存在,将始终创建一个会话 •ifRequired - 仅在需要时创建会话(默认) •never - 框架永远不会创建会话本身,但如果它已经存在,它将使用一个 •stateless - Spring Security不会

  • 话说Spring Security权限管理(源码详解)

    最近项目需要用到Spring Security的权限控制,故花了点时间简单的去看了一下其权限控制相关的源码(版本为4.2). AccessDecisionManager spring security是通过AccessDecisionManager进行授权管理的,先来张官方图镇楼. AccessDecisionManager AccessDecisionManager 接口定义了如下方法: //调用AccessDecisionVoter进行投票(关键方法) void decide(Authent

  • Spring Security系列教程之会话管理处理会话过期问题

    目录 前言 一. 会话过期 1. 会话过期概念 2. Session的超时时间 3. 会话过期时的处理策略 二. 会话过期时的处理策略(一) 1. 配置会话过期时间 2. 定义测试接口 3. 配置跳转到某个URL 4. 启动测试 三. 会话过期时的处理策略(二) 1. 自定义MyInvalSessionStrategy类 2. 配置自定义过期策略 前言 在上一章节中,一一哥 给各位讲解了HTTP协议.会话.URL重新.会话固定攻击等概念,并且实现了对会话固定攻击的防御拦截. 在Spring Se

  • Spring Boot系列教程之死信队列详解

    前言 在说死信队列之前,我们先介绍下为什么需要用死信队列. 如果想直接了解死信对接,直接跳入下文的"死信队列"部分即可. ack机制和requeue-rejected属性 我们还是基于上篇<Spring Boot系列--7步集成RabbitMQ>的demo代码来说. 在项目springboot-demo我们看到application.yaml文件部分配置内容如下 ... listener: type: simple simple: acknowledge-mode: aut

  • Spring Boot系列教程之日志配置

    前言 日志,通常不会在需求阶段作为一个功能单独提出来,也不会在产品方案中看到它的细节.但是,这丝毫不影响它在任何一个系统中的重要的地位. 为了保证服务的高可用,发现问题一定要即使,解决问题一定要迅速,所以生产环境一旦出现问题,预警系统就会通过邮件.短信甚至电话的方式实施多维轰炸模式,确保相关负责人不错过每一个可能的bug. 预警系统判断疑似bug大部分源于日志.比如某个微服务接口由于各种原因导致频繁调用出错,此时调用端会捕获这样的异常并打印ERROR级别的日志,当该错误日志达到一定次数出现的时候

  • 详解Spring Security中权限注解的使用

    目录 1. 具体用法 2. SpEL 3. @PreAuthorize 最近有个小伙伴在微信群里问 Spring Security 权限注解的问题: 很多时候事情就是这么巧,松哥最近在做的 tienchin 也是基于注解来处理权限问题的,所以既然大家有这个问题,咱们就一块来聊聊这个话题. 当然一些基础的知识我就不讲了,对于 Spring Security 基本用法尚不熟悉的小伙伴,可在公众号后台回复 ss,有原创的系列教程. 1. 具体用法 先来看看 Spring Security 权限注解的具

  • Spring Security 自动踢掉前一个登录用户的实现代码

    登录成功后,自动踢掉前一个登录用户,松哥第一次见到这个功能,就是在扣扣里边见到的,当时觉得挺好玩的. 自己做开发后,也遇到过一模一样的需求,正好最近的 Spring Security 系列正在连载,就结合 Spring Security 来和大家聊一聊这个功能如何实现. 本文是本系列的第十三篇,阅读前面文章有助于更好的理解本文: 挖一个大坑,Spring Security 开搞! 松哥手把手带你入门 Spring Security,别再问密码怎么解密了 手把手教你定制 Spring Securi

  • Spring Boot中整合Spring Security并自定义验证代码实例

    最终效果 1.实现页面访问权限限制 2.用户角色区分,并按照角色区分页面权限 3.实现在数据库中存储用户信息以及角色信息 4.自定义验证代码 效果如下: 1.免验证页面 2.登陆页面 在用户未登录时,访问任意有权限要求的页面都会自动跳转到登陆页面. 3.需登陆才能查看的页面 用户登陆后,可以正常访问页面资源,同时可以正确显示用户登录名: 4.用户有角色区分,可以指定部分页面只允许有相应用户角色的人使用 4.1.只有ADMIN觉得用户才能查看的页面(权限不足) 4.2.只有ADMIN觉得用户才能查

  • Spring Security实现两周内自动登录"记住我"功能

    本文是Spring Security系列中的一篇.在上一篇文章中,我们通过实现UserDetailsService和UserDetails接口,实现了动态的从数据库加载用户.角色.权限相关信息,从而实现了登录及授权相关的功能.这一节就在此基础上新增,登录过程中经常使用的"记住我"功能,也就是我们经常会在各种网站登陆时见到的"两周内免登录","三天内免登录"的功能.该功能的作用就是:当我们登录成功之后,一定的周期内当我们再次访问该网站,不需要重新登

  • Spring Security实现两周内自动登录"记住我"功能

    本文是Spring Security系列中的一篇.在上一篇文章中,我们通过实现UserDetailsService和UserDetails接口,实现了动态的从数据库加载用户.角色.权限相关信息,从而实现了登录及授权相关的功能.这一节就在此基础上新增,登录过程中经常使用的"记住我"功能,也就是我们经常会在各种网站登陆时见到的"两周内免登录","三天内免登录"的功能.该功能的作用就是:当我们登录成功之后,一定的周期内当我们再次访问该网站,不需要重新登

  • Spring Security OAuth过期的解决方法

    最近一段时间,大家在用 Spring Security OAuth2 时可能发现有很多类过期了. 大家在选择 OAuth2 依赖的时候,可能也会困惑,有好几个地方都可以选: 那么到底选择哪一个依赖合适呢?这不同的依赖又有什么区别?今天松哥就来和大家聊一聊 Spring Security 中关于 OAuth2 的恩怨. 前言 先来大致介绍一下 OAuth2 在 Spring 框架中的发展历程. 大约十年前,Spring 引入了一个社区驱动的开源项目 Spring Security OAuth,并将

随机推荐