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

 更新时间:2021年10月14日 10:47:40   作者:一一哥Sun  
会话过期,是指当用户登录网站后,较长一段时间没有与服务器进行交互,将会导致服务器上的用户会话数据(即session)被销毁。这篇文章主要介绍了Spring Security系列教程之会话管理处理会话过期问题,需要的朋友可以参考下

前言

在上一章节中,一一哥 给各位讲解了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会话过期内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SprinBoot如何集成参数校验Validator及参数校验的高阶技巧

    SprinBoot如何集成参数校验Validator及参数校验的高阶技巧

    这篇文章主要介绍了SprinBoot如何集成参数校验Validator及参数校验的高阶技巧包括自定义校验、分组校验,本文分步骤给大家介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • Java 时间相减算法题解示例

    Java 时间相减算法题解示例

    这篇文章主要为大家介绍了Java 时间相减算法题解示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • ssm框架上传图片保存到本地和数据库示例

    ssm框架上传图片保存到本地和数据库示例

    本篇文章主要介绍了ssm框架上传图片保存到本地和数据库示例,主要使用了Spring+SpringMVC+MyBatis框架集合,有兴趣的可以了解一下。
    2017-03-03
  • JavaWeb之监听器案例讲解

    JavaWeb之监听器案例讲解

    这篇文章主要介绍了JavaWeb之监听器案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • RateLimiter 源码分析

    RateLimiter 源码分析

    本文主要对ratelimiter的常用方法以及源码进行了分析解读,具有一定参考价值,需要的朋友可以了解下。
    2017-09-09
  • java多线程解决生产者消费者问题

    java多线程解决生产者消费者问题

    这篇文章主要介绍了java多线程解决生产者消费者问题的方法,实例分析了java采用多线程的方法解决生产者消费者问题的相关技巧,需要的朋友可以参考下
    2015-05-05
  • Spring实战之Bean的后处理器操作示例

    Spring实战之Bean的后处理器操作示例

    这篇文章主要介绍了Spring实战之Bean的后处理器操作,结合实例形式详细分析了Bean的后处理器相关配置、操作方法及使用注意事项,需要的朋友可以参考下
    2019-12-12
  • springboot集成mqtt超级详细步骤

    springboot集成mqtt超级详细步骤

    这篇文章主要介绍了springboot集成mqtt超级详细步骤,本文分步骤结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • 深入了解Spring控制反转IOC原理

    深入了解Spring控制反转IOC原理

    IOC-Inversion of Control,即控制反转。它不是什么技术,而是一种设计思想。这篇文章将为大家介绍一下Spring控制反转IOC的原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • Java中List转字符串的5种方法解析

    Java中List转字符串的5种方法解析

    在Java中将一个List转换为字符串有多种方法,下面这篇文章主要给大家介绍了关于Java中List转字符串的5种方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11

最新评论