栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringSecurity (七)session管理(会话管理)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringSecurity (七)session管理(会话管理)

一.项目搭建

pom.xml



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.1
         
    
    com.huang
    test
    0.0.1-SNAPSHOT
    test
    test
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-security
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.security
            spring-security-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    



application.properties

spring.security.user.name=zhangsan
spring.security.user.password=123
server.port=8081

HelloController

		package com.huang.test;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class    HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

SecurityConfig关键,过滤器配置在下文

二.配置会话管理 2.1过滤器链配置会话管理

默认情况下账户登录数量没有限制,但是有的业务需求一个账户只能登录一台设备,例如qq,那我们应该怎么做呢?

对,没错,继续配置我们的SecurityConfig里的过滤器链,securityFilterChain

  package com.huang.test.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.session.HttpSessionEventPublisher;

@Configuration
public class    SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                //SessionManagementFilter
                .sessionManagement()
                //设置会话的最大并发数,设置一个用户只可以在一台设备上登录
                //默认情况下,达到最大会话并发数之后,会挤掉上一次的登录
                .maximumSessions(1)
                //达到最大会话数的时候,是否要阻止下一个登录(自己设置登录)
                .maxSessionsPreventsLogin(true)
                .and().and()
                .csrf().disable();
        return http.build();
    }

}


2.2 配置会话管理的关键代码(加入过滤器链)

关键代码
注意最下面是两个.and()为了保证返回的值是HttpSession

.and()
//SessionManagementFilter
 .sessionManagement()
 //设置会话的最大并发数,设置一个用户只可以在一台设备上登录
.maximumSessions(1)
//达到最大会话数的时候,是否要阻止下一个登录,
 .and().and()

2.3 会话管理测试为什么要用两个浏览器

测试.(用两个浏览器登录,因为用一个浏览器开两个窗口会有cookie缓存,看似是一个用户登录两次,其实跟你同一个电脑登录qq,然后把qq下了,又在这个电脑上登录qq一样,而开两个浏览器登录qq就相当于两个电脑登录一个qq,这样才能看出来测试结果)

浏览器一:

浏览器二:

再次登录浏览器一:

如上所示,实现了会话管理

2.4 .and().and()的原因

上面注意一个关键:加两个.and()
在这里需要两个.and()保证返回的是HttpSecurity,因为前面配置完了最大session数,还可以配置session的策略,(这个策略是t掉之前的用户如qq,还是禁止登录)Spring Security默认的会话管理策略是t掉上一次的登录


2.5 默认会话管理策略和策略配置

先登录浏览器1用户,再登录浏览器二用户,刷新浏览器一,报出

Spring Security默认的会话管理策略是t掉上一次的登录,当然我们也可以去调整我们的策略如下图:

2.5.1 默认会话管理策略配置与测试 2.5.2 禁止登录会话管理策略配置与测试

securityFilterChain关键代码:

 //SessionManagementFilter
 .sessionManagement()
//设置会话的最大并发数,设置一个用户只可以在一台设备上登录
 //默认情况下,达到最大会话并发数之后,会挤掉上一次的登录
 .maximumSessions(1)
 //达到最大会话数的时候,是否要阻止下一个登录
.maxSessionsPreventsLogin(true)
 .and().and()

浏览器一:登录浏览器一

浏览器二:试图登录浏览器二,报出

登录完之后,再登录新的是没有办法并且会给出提示的,那我们想要登录后再去登录怎么办?把第一个用户注销试试,出现如下图

浏览器1注销登录

浏览器2登录报错

还是没办法继续登录,那这是为什么?

2.5.3 为什么禁止登录策略,注销了浏览器一的用户后还是没办法再第二个浏览器登录

这是为什么?

涉及到了会话管理的实现原理

在服务端,spring Security维护了一个会话注册表,所有登录上来的用户,都会注册到这个会话注册表中所谓的会话注册表,本质是一个Map集合,Map的key是当前用户对象!注意,是当前用户的对象哦,Map的value是一个集合,这个集合中保存着这个用户的所有会话。如下结构Map(这里存储的session是包装后的session).这个value对应着这个用户的所有会话session,每次登录后就能够去Map里面拿出来这个用户的所有会话然后判断一下(set)就知道该不该登录了,当用户注销登录的时候,用户的session会被自动销毁,但是Map中的List集合中的session并不会自动移除,所以,就导致每次登录的时候都会判断为session已经登录,所以我们应当在用户注销登录的时候,将list集合中把用户对应的会话session移除掉,

具体操作步骤
如下所示:

securityConfig中加入配置–监听HttpSession的销毁操作

这个监听器的作用:

这个事件,可以监听到 HttpSession 的销毁操作,当有 HttpSession 销毁的时候,就将这个销毁的事件广播出去,Map收到通知,就会从value即list集合中把对应的会话session给移除

 
    @Bean
    HttpSessionEventPublisher sessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }

加了监听HttpSession的销毁操作的配置HttpsessionEventPublisher之后的测试:

浏览器一:

浏览器二:登录成功

三.那么如果我们要传递json我们应该怎么配置我们的SecurityConfig呢
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1020782.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号