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

网友投稿 793 2022-12-01

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

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

目录前言一. 会话过期1. 会话过期概念2. Session的超时时间3. 会话过期时的处理策略二. 会话过期时的处理策略(一)1. 配置会话过期时间2. 定义测试接口3. 配置跳转到某个URL4. 启动测试三. 会话过期时的处理策略(二)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()

YNORqvEjDb .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();

}

}

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:(Matlab实现)基于蒙特卡洛模拟的大规模电动车充电模型
下一篇:使用Android内部的DownloadProvider下载文件,并获取cache权限
相关文章

 发表评论

暂时没有评论,来抢沙发吧~