基于活动会话授予Spring安全权限

时间:2017-01-04 17:27:09

标签: spring spring-security spring-session

是否有一种直接的方法可以根据当前是否存在活动会话来授予Spring Security / Spring Session权限?我想要做的是一次将ADMIN权限限制为单个活动会话。

例如:

  • 用户A和用户B都可能被授予ADMIN权限。
  • 用户A登录。
    • 创建会话并授予权限ADMIN
  • 当用户A的会话仍处于活动状态时,用户B登录。
    • 创建会话和授予权限USER

如果用户B在没有其他会话处于活动状态时登录,则授予权限ADMIN。 如果用户A已经存在与用户A关联的活动会话时再次登录,则将权限USER与新会话关联(使权限ADMIN与用户A的“旧”会话关联)。

2 个答案:

答案 0 :(得分:1)

假设已配置SessionRegistryHttpSessionEventPublisher,我们可以按如下方式检查是否存在活动的管理会话:

public boolean adminActiveSessionExists () {

    for(Object principal: sessionRegistry.getAllPrincipals()) {
        /* write a method hasAdminAuthority to check if principal is admin */
        if (hasAdminAuthority(principal)) {
            /* Check if there is any active admin session */
            if (sessionRegistry.getAllSessions(principal, false)
                    .stream().anyMatch(sessionInfo -> !sessionInfo.isExpired())) {

                return true;
            }
        }
    }

    return false;
}

然后,您可以在身份验证逻辑中使用它来授予权限。请注意,这仅适用于单个服务器。

答案 1 :(得分:0)

您的要求听起来像ConcurrentSessionControlAuthenticationStrategy但基于授予的权限而非主体(用户名)。

这很复杂,因为用于检索会话的API(Spring Session' s FindByIndexNameSessionRepository)目前不支持按此类标准检索会话(授予权限),或从基础会话存储中检索所有会话。因此,您必须扩展会话存储以提供此类功能。

或者,您可以使用不同的方法 - 您可以让一个用户获得ADMIN权限,将该用户的并发会话数限制为一个会话,并使用Spring Session' { {3}}在需要时切换到ADMIN用户。不知道这对你是否可以接受,但它可能是一种选择。