springSecurity学习之springSecurity用户单设备登录

用户只能单设备登录

有时候在同一个系统中,只允许一个用户在一个设备登录。

之前的登陆者被顶掉

将最大会话数设置为1就可以保证用户只能同时在一个设备上登录

java 复制代码
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.
            .anyRequest().authenticated() // 其他需要认证
            .and()
            .csrf().disable() // 关闭csrf跨站请求伪造防护
            // 设置一个用户只能在一个设备上登录 设置最大会话数
            .sessionManagement().maximumSessions(1)
    ;

}

不允许后来者登录

java 复制代码
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.
            .anyRequest().authenticated() // 其他需要认证
            .and()
            .csrf().disable() // 关闭csrf跨站请求伪造防护
            // 设置一个用户只能在一个设备上登录 设置最大会话数
            .sessionManagement().maximumSessions(1)
            .maxSessionsPreventsLogin(true) // 禁止后来者登录

    ;

}

源码解读

ConcurrentSessionControlAuthenticationStrategy类

java 复制代码
public void onAuthentication(Authentication authentication,
      HttpServletRequest request, HttpServletResponse response) {

  // 获取当前用户的所有session
   final List<SessionInformation> sessions = sessionRegistry.getAllSessions(
         authentication.getPrincipal(), false);

   int sessionCount = sessions.size();
  // 同时允许几个session存在
   int allowedSessions = getMaximumSessionsForThisUser(authentication);
// 当前登录的数量小于允许的数量
   if (sessionCount < allowedSessions) {
      // They haven't got too many login sessions running at present
      return;
   }
// 不进行限制
   if (allowedSessions == -1) {
      // We permit unlimited logins
      return;
   }
// 已经达到允许数量了
   if (sessionCount == allowedSessions) {
     // 当前session 是否为null
      HttpSession session = request.getSession(false);

      if (session != null) { // 不为null则判断一下是否有与当前session同一个sessionId的
         // Only permit it though if this request is associated with one of the
         // already registered sessions
         for (SessionInformation si : sessions) {
            if (si.getSessionId().equals(session.getId())) {
               return;
            }
         }
      }
      // If the session is null, a new one will be created by the parent class,
      // exceeding the allowed number
   }
	// 这里说明session已超过限制数量了
   allowableSessionsExceeded(sessions, allowedSessions, sessionRegistry);
}


protected void allowableSessionsExceeded(List<SessionInformation> sessions,
			int allowableSessions, SessionRegistry registry)
			throws SessionAuthenticationException {
  // exceptionIfMaximumExceeded该值就是配置的maxSessionsPreventsLogin
		if (exceptionIfMaximumExceeded || (sessions == null)) {
			throw new SessionAuthenticationException(messages.getMessage(
					"ConcurrentSessionControlAuthenticationStrategy.exceededAllowed",
					new Object[] { Integer.valueOf(allowableSessions) },
					"Maximum sessions of {0} for this principal exceeded"));
		}

		// Determine least recently used session, and mark it for invalidation
		SessionInformation leastRecentlyUsed = null;

		for (SessionInformation session : sessions) {
			if ((leastRecentlyUsed == null)
					|| session.getLastRequest()
							.before(leastRecentlyUsed.getLastRequest())) {
				leastRecentlyUsed = session;
			}
		}

		leastRecentlyUsed.expireNow();
	}

https://zhhll.icu/2023/框架/springSecurity/6.用户只能单设备登录/

相关推荐
TeDi TIVE16 小时前
springboot和springframework版本依赖关系
java·spring boot·后端
二哈赛车手16 小时前
新人笔记---ES和kibana启动问题以及一些常用的linux的错误排查方法,以及ES,数据库泄密解决方案[超详细]
java·linux·数据库·spring boot·笔记·elasticsearch
嵌入式×边缘AI:打怪升级日志16 小时前
嵌入式Linux开发核心自测题(全系列精华浓缩)
java·linux·运维
FQNmxDG4S17 小时前
JVM内存模型详解:堆、栈、方法区与垃圾回收
java·jvm·算法
jason.zeng@150220717 小时前
Androidr入门环境搭建
java·kotlin
摇滚侠17 小时前
整洁的桌面和任务栏 Java 开发工程师提效方法
java·开发语言
每天都要加油呀!18 小时前
多租户中间件适配
java·多租户
014-code18 小时前
Java 并发中的原子类
java·开发语言·并发
AI人工智能+电脑小能手18 小时前
【大白话说Java面试题】【Java基础篇】第29题:静态代理和动态代理的区别是什么
java·开发语言·后端·面试·代理模式
善恶怪客18 小时前
Java-数组和可变参数
java·开发语言