springsecurity中session的并发控制

文章目录

  • 1 是什么?
  • 2 超过最大并发数量时,踢掉前面的登陆
  • 3 超过最大并发数量时,阻止后面的登陆

项目源码地址 https://github.com/nieandsun/security

1 是什么?

以腾讯视频会员为例,假如我的账号买了会员,则我可以享受看视频免广告,某些热门电视剧提前看等福利。若我的朋友也想享受这些福利又不想花钱买会员,则我可以让他用我的号登陆。但是假如我有很多很多的朋友都不想买会员,都想用我的号登陆,那腾讯肯定感觉自己就亏了,所以腾讯视频最大可同时登陆的设备是有数量限制的,超过这个限制,前面的账户就会被踢下来,这就是所谓的session并发控制。
springsecurity在解决该问题时有两种策略

  • 超过设置的最大session并发数量时,把之前的session失效掉,即踢掉前面的登陆
  • 超过设置的最大session并发数量时,阻止后面的登陆

2 超过最大并发数量时,踢掉前面的登陆

  • 在配置文件BrowserSecurityConfig里指定最大的并发数量
//session相关的控制
.sessionManagement()
  //指定session超时跳向的url
  .invalidSessionUrl("/session/invalid")
  //指定最大的session并发数量---即一个用户只能同时在一处登陆(腾讯视频的账号好像就只能同时允许2-3个手机同时登陆)
  .maximumSessions(1)
  //超过最大session并发数量时的策略
  .expiredSessionStrategy(new NRSCExpiredSessionStrategy())
  • 超过最大session并发数量时的策略
package com.nrsc.security.browser.session;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.nrsc.security.enums.ResultEnum;
import com.nrsc.security.utils.ResultVOUtil;
import com.nrsc.security.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.session.SessionInformationExpiredEvent;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @author : Sun Chuan
 * @date : 2019/9/21 17:14
 * Description:
 * 如果设置的session并发策略为一个账户第二次登陆会将第一次给踢下来
 * 则第一次登陆的用户再访问我们的项目时会进入到该类
 * event里封装了request、response信息
 */
@Slf4j
public class NRSCExpiredSessionStrategy implements SessionInformationExpiredStrategy {
     

    @Override
    public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {
     
        String header = event.getRequest().getHeader("user-agent");
        log.info("浏览器信息为:{}", header);

        //告诉前端并发登陆异常
        event.getResponse().setContentType("application/json;charset=UTF-8");
        event.getResponse().getWriter().write("并发登陆!!!");
    }
}

3 超过最大并发数量时,阻止后面的登陆

//session相关的控制
.sessionManagement()
  //指定session超时跳向的url
  .invalidSessionUrl("/session/invalid")
  //指定最大的session并发数量---即一个用户只能同时在一处登陆(腾讯视频的账号好像就只能同时允许2-3个手机同时登陆)
  .maximumSessions(1)
  //当超过指定的最大session并发数量时,阻止后面的登陆(感觉貌似很少会用到这种策略)
  .maxSessionsPreventsLogin(true)
  //超过最大session并发数量时的策略
  .expiredSessionStrategy(new NRSCExpiredSessionStrategy())

你可能感兴趣的:(spring-security,session并发控制)