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会话过期内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-10-12

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

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

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实现权限管理示例,具体如下: 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

Spring Boot中使用 Spring Security 构建权限系统的示例代码

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作. 权限控制是非常常见的功能,在各种后台管理里权限控制更是重中之重.在Spring Boot中使用 Spring Security 构建权限系统是非常轻松和简单的.下面我们就来快速入门 Spring Security .在开始前我们需要一对

spring security自定义决策管理器

首先介绍下Spring的决策管理器,其接口为AccessDecisionManager,抽象类为AbstractAccessDecisionManager.而我们要自定义决策管理器的话一般是继承抽象类而不去直接实现接口. 在Spring中引入了投票器(AccessDecisionVoter)的概念,有无权限访问的最终觉得权是由投票器来决定的,最常见的投票器为RoleVoter,在RoleVoter中定义了权限的前缀,先看下Spring在RoleVoter中是怎么处理授权的. public int

SpringBoot与spring security的结合的示例

权限控制,也是我们再日常开发中经常遇到的场景,需要根据用户的角色决定是否可以看到某个资源.目前,市面上此类框架主要有shiro与我们今天要讲到的spring security.关于权限的控制有复杂的控制,例如几乎每个公司都有单点登录系统,根据用户名来到数据库中拿到对应的权限,在展示该权限下能看到的资源.还有一种就是简单的控制,也就是我们今天所要提到的.将账号,密码,角色配置到代码中,也可以进行简单的控制,缺点不言而喻,扩展性不好,只有固定的账号,但是作为演示还是够用的. 好了废话不多说,上pom

Spring Security 安全认证的示例代码

1.1 动态用户 1.1.1 放行资源   如果我们再配置的时候没有放行登录页等一些不需要登录就可以看到的资源,那么访问的时候就会全部拦截导致访问不到.所以我们要配置放行一些无需登录就可以看到的资源. <?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:be

详解spring security之httpSecurity使用示例

httpSecurity 类似于spring security的xml配置文件命名空间配置中的<http>元素.它允许对特定的http请求基于安全考虑进行配置.默认情况下,适用于所有的请求,但可以使用requestMatcher(RequestMatcher)或者其它相似的方法进行限制. 使用示例: 最基本的基于表单的配置如下.该配置将所有的url访问权限设定为角色名称为"ROLE_USER".同时也定义了内存认证模式:使用用户名"user"和密码&qu

详解spring整合shiro权限管理与数据库设计

之前的文章中我们完成了基础框架的搭建,现在基本上所有的后台系统都逃不过权限管理这一块,这算是一个刚需了.现在我们来集成shiro来达到颗粒化权限管理,也就是从连接菜单到页面功能按钮,都进行权限都验证,从前端按钮的显示隐藏,到后台具体功能方法的权限验证. 首先要先设计好我们的数据库,先来看一张比较粗糙的数据库设计图: 具体的数据库设计代码 /* Navicat MySQL Data Transfer Source Server : 本机 Source Server Version : 50537

Spring Security认证提供程序示例详解

1.简介 本教程将介绍如何在Spring Security中设置身份验证提供程序,与使用简单UserDetailsService的标准方案相比,提供了额外的灵活性. 2. The Authentication Provider Spring Security提供了多种执行身份验证的选项 - 所有这些都遵循简单的规范 - 身份验证请求由Authentication Provider处理,并且返回具有完整凭据的完全身份验证的对象. 标准和最常见的实现是DaoAuthenticationProvide

Spring Security OAuth2认证授权示例详解

本文介绍了如何使用Spring Security OAuth2构建一个授权服务器来验证用户身份以提供access_token,并使用这个access_token来从资源服务器请求数据. 1.概述 OAuth2是一种授权方法,用于通过HTTP协议提供对受保护资源的访问.首先,OAuth2使第三方应用程序能够获得对HTTP服务的有限访问权限,然后通过资源所有者和HTTP服务之间的批准交互来让第三方应用程序代表资源所有者获取访问权限. 1.1 角色 OAuth定义了四个角色 资源所有者 - 应用程序的

Spring Security 单点登录简单示例详解

Overview 最近在弄单点登录,踩了不少坑,所以记录一下,做了个简单的例子. 目标:认证服务器认证后获取 token,客户端访问资源时带上 token 进行安全验证. 可以直接看源码. 关键依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2