SpringSecurity整合SpringSession解决集群会话问题

 
读《SpringSecurity实战(陈木鑫)》
 
陈木鑫老师阐述的观点是,解决集群会话的常见方案有三种:
1.session保持
2.session复制
3.session共享

 
session保持也叫粘滞会话
 
书中说,通常采用IP哈希负载策略将来自相同客户端的请求转发至相同的服务器进行处理。
 
session复制
 
是指在集群服务器之间同步session数据,已达到各个实例之间会话状态一致的做法。
 
session共享
 
是指将session从服务器内存抽离出来,集中存储到独立的数据容器,并由各个服务器共享。
 

<!--spring session核心依赖-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-core</artifactId>
</dependency>
<!--spring session对接Redis的必要依赖-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
<!--spring boot整合的Redis的核心依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
package com.zcw.demospringsecurity.demo11;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;

import javax.swing.*;

/**
 * @ClassName : HttpSessionConfig
 * @Description :启用基于Redis的HttpSession实现
 * @Author : Zhaocunwei
 * @Date: 2020-04-12 13:56
 */
@EnableRedisHttpSession
public class HttpSessionConfig {

    @Bean
    public RedisConnectionFactory connectionFactory(){
        return new JedisConnectionFactory();
    }
    @Autowired
    private FindByIndexNameSessionRepository  sessionRepository;
    /**
     * SpringSessionBackedSessionRegistry是session为Spring Security
     * 提供的用于集群环境下控制会话并发的会话注册表实现类
     */
    @Bean
    public SpringSessionBackedSessionRegistry sessionBackedSessionRegistry(){
        return new SpringSessionBackedSessionRegistry(sessionRepository);
    }
    //httpSession的事件监听,改用session提供的会话注册表
    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher(){
        return new HttpSessionEventPublisher();
    }
}

package com.zcw.demospringsecurity.demo11;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;

/**
 * @ClassName : WebSecurityConfig
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-04-12 15:29
 */
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private SpringSessionBackedSessionRegistry redisSessionRegistry;

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.authorizeRequests()
                .antMatchers("/admin/**")
                .hasAuthority("ROLE_ADMIN")
                .antMatchers("/user/**")
                .hasRole("USER")
                .antMatchers("/app/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf()
                .disable()
                .formLogin()
                .and()
                .sessionManagement()
                .maximumSessions(1)
                //使用session提供的会话注册表
                .sessionRegistry(redisSessionRegistry);
    }
}

发布了458 篇原创文章 · 获赞 15 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_32370913/article/details/105552454