Spring Security 会话共享

会话共享

  • 依赖
<!-- session share -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
</dependency>
  • 配置redis
spring:
	redis:
		host: localhost
		port: 6379
  • 配置security
	// 注入

    private final FindByIndexNameSessionRepository sessionRepository;

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SpringSessionBackedSessionRegistry(sessionRepository);
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
		 http.sessionManagement() // 开启会话管理
                .maximumSessions(1) // 最大同时登陆数
                // .and().invalidSessionUrl("invalidSession") // 错误session处理
                // 属于SessionManagementFilter重定向
                // .expiredUrl("/expired") // 被挤下线的会话过期处理 属于ConcurrentSessionFilter将重定向到expiredUrl
                .expiredSessionStrategy( // 过期策略(前后端分离)
                        event -> {
                            HttpServletResponse response = event.getResponse();
                            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                            String json =
                                    "{\"success\":false,\"message\":\"SESSION_INVALID\",\"code\":401}";
                            response.getWriter().println(json);
                        })
                .maxSessionsPreventsLogin(true) // 登陆后禁止再次登陆(不允许二次登陆)
                // session 共享
                .sessionRegistry(sessionRegistry())
        ;
    }

会话次数限制Bug

如果继承 UserDetails 的实体类没有重写 equals 和 hashCode 方法, 或调用了父类的方法 (super), 但父类没重写, 导致比对失败, 可以无限制登陆.

解决办法出处: https://stackoverflow.com/questions/51916715/concurrent-session-management-not-working-i-have-followed-the-documentation-bu

跨域

  • 单独: @CrossOrigin(origins=“http://允许的域”) 注解(类、方法)

  • 全局: addCrosMapping 重写WebMvcCofingurerComposite#addCorsMapping 方法来实现

  • 全局: 过滤器Filter方案

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        // Cors 配置信息
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("https://www.leetcode.com:8080"); // 允许的域
        config.setAllowCredentials(true); // 允许发送 cookie 信息
        config.addAllowedMethod("*");
        config.addAllowedHeader("*"); // 允许头信息
        config.setMaxAge(3600L);

        // 添加映射路径, 拦截一切请求
        UrlBasedCorsConfigurationSource configSrouce = new UrlBasedCorsConfigurationSource();
        configSrouce.registerCorsConfiguration("/**", config);

		// 返回新的 CorsFilter
        return new CorsFilter(configSrouce);
    }
}

Cookie 共享问题 (session共享)

由于浏览器是根据应用的 域名IP地址 储存 Cookie 的 (也就是 sessionId ), 相同域名或 IP地址, 即使端口不同, 相互之间也会干扰, 造成 session共享的问题, 也就是 A 项目的 sessionId 用到了 B 项目上, 导致 B 项目判断 session 不存在.

解决办法也很简单, 使名称也就是 key (JSESSIONID=xxxxx) 不重复就行了.

server.servlet.session.cookie.name=new_name
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值