• security 会话并发管理


    一、简介

    会话指得是浏览器和服务端通过session交互过程

    二、会话并发管理

    1、什么是会话并发

    当前系统中,同一个用户是否可以在多台设备登录,springsecurity默认没有限制,可以在多台设备登录,可以在springsecurity中配置管理

    2、代码

    引入security不做任何配置 默认同一个账号是可以在多个浏览器登录访问系统

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .and()
                    .csrf().disable()
                    .sessionManagement()//开启会话管理
                    .maximumSessions(1);//同一个账号只能在一个浏览器登录
        }
    
        /**
         *找个bean可以不加,但是建议加上
         * security提供一个map来集护当前http session记录 实现会话并发管理,当登录时候增加一条 ,退出时从集合移除一个
         */
        @Bean
        public HttpSessionEventPublisher httpSessionEventPublisher(){
            return new HttpSessionEventPublisher();
        }
    }

    当多个浏览器登录时候出现如下提示

    This session has been expired (possibly due to multiple concurrent logins being attempted as the same user).

    会话失效我们该如何改变找个提示?

    3、会话被挤下线时处理

    3.1、传统web开发

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .and()
                    .csrf().disable()
                    .sessionManagement()
                    .maximumSessions(1)
                    .expiredUrl("/login");//被挤下线时候跳转地址
        }
        @Bean
        public HttpSessionEventPublisher httpSessionEventPublisher(){
            return new HttpSessionEventPublisher();
        }
    }

    3.2、前后端分离

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .and()
                    .csrf().disable()
                    .sessionManagement()
                    .maximumSessions(1)
                    .expiredSessionStrategy(event -> {
                        HttpServletResponse response = event.getResponse();
                        Map map = new HashMap<>();
                        map.put("code",500);
                        map.put("msg","当前账号异地登录");
                        String result = new ObjectMapper().writeValueAsString(map);
                        response.setContentType("application/json;charset=UTF-8");
                        response.getWriter().println(result);
                        response.flushBuffer();
                    });//参数是个函数式接口 直接用lambda处理
        }
        @Bean
        public HttpSessionEventPublisher httpSessionEventPublisher(){
            return new HttpSessionEventPublisher();
        }
    }

    4、禁止再次登录

    默认是被挤下线方式 可以设置后来者无法登录

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .and()
                    .csrf().disable()
                    .sessionManagement()
                    .maximumSessions(1)
                    .expiredUrl("/login")
                    .maxSessionsPreventsLogin(true);//一旦登录 禁止再次登录
        }
        @Bean
        public HttpSessionEventPublisher httpSessionEventPublisher(){
            return new HttpSessionEventPublisher();
        }
    }

    5、分布式会话共享

    上面会话都是通过内存中的map集中管理,所以无法在分布式集群系统中共享,要在集群中使用,就要用spring-session集合redis实现session共享

    引入依赖

            
                org.springframework.boot
                spring-boot-starter-data-redis
            
            
                org.springframework.session
                spring-session-data-redis
            

    系统配置文件配置redis

    spring.redis.port=6379
    spring.redis.url=localhost

    security配置

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        //注入session管理方案
        @Autowired
        private FindByIndexNameSessionRepository findByIndexNameSessionRepository;
        
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .and()
                    .csrf().disable()
                    .sessionManagement()
                    .maximumSessions(1)
                    .expiredUrl("/login")
                    .sessionRegistry(sessionRegistry())//将session交给谁管理
                    .maxSessionsPreventsLogin(true);
        }
    
        /**
         * 创建session 同步到redis的方案
         */
        @Bean
        public SpringSessionBackedSessionRegistry sessionRegistry(){
            return new SpringSessionBackedSessionRegistry(findByIndexNameSessionRepository);
        }
    }
  • 相关阅读:
    【目标检测】大图包括标签切分,并转换成txt格式
    《代码大全2》第7章 高质量的子程序
    前端⽣成 json ⽂件并导出
    动态尺寸模型优化实践之Shape Constraint IR Part II
    2022-08-30 第六小组 瞒春 学习笔记
    STM32项目开发实战教程--CUME MX HAL库开发介绍
    2022上海区块链国际周将全程线上举办,直播预约已开启
    Python ML实战-工业蒸汽量预测02-数据探索
    万界星空科技MES系统软件体系架构及应用
    RocketMQ消息消费(Consumer)源码解析
  • 原文地址:https://blog.csdn.net/qq_34491508/article/details/126102477