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.用户只能单设备登录/

相关推荐
知识搬运临时工7 分钟前
JVM 删掉偏向锁之后,一次无竞争锁从 0.3 纳秒变成 5.4 纳秒
java
IT枫斗者枫哥11 分钟前
用了BigDecimal还差一分?用四组Java代码查清原因
java·后端
一条泥憨鱼1 小时前
【消息队列】ACK确认了什么:消息队列可靠投递的完整链路
java·后端·kafka·消息队列·rabbitmq
从琳开始9891 小时前
网络原理入门(二)------OSI七层模型?TCP/IP五层(四层)模型原来是这样的
java·网络·tcp/ip·java-ee·php
文丑颜不良啊2 小时前
LeetCode1861~1880题目解析
java·leetcode
Flynn Liang2 小时前
AgentScope Java 深度解析:ReActAgent、HarnessAgent 与多智能体编排——JVM 上的自治 Agent 底座
java·大模型·架构设计·ai agent·spring ai·langchain4j·agentscope
Flynn Liang2 小时前
上线后怎么排查 AI 调用?Spring AI Observability:token/延迟/成本埋点与全链路追踪
java·人工智能·spring·监控·可观测性·observability·springai
文丑颜不良啊2 小时前
LeetCode1921~1940题目解析
java·leetcode
Tt有了t2 小时前
设计模式速查
java·python·设计模式
Thomas.Sir2 小时前
第15课:SpringBoot连接池详解:HikariCP配置、调优、监控,4.x连接池新特性
java·spring boot