如何使用Spring Security重新加载用户更新的权限

2022-08-31 16:10:12

我正在使用Spring Security通过OpenID进行身份验证的应用程序。当用户登录时,某些权限将加载到他的会话中。

我有具有完全权限的用户,可以修改其他用户的权限(撤销,添加角色)。我的问题是,如何动态更改用户会话权限?(无法使用 SecurityContextHolder,因为我想更改另一个用户会话)。

简单的方法:使用户会话无效,但如何?更好的方法:刷新与新权限的用户会话,但如何?


答案 1

如果您需要动态更新已登录用户的权限(无论出于何种原因,当这些权限发生变化时),则无需注销并登录,当然,您只需要在Spring中重置对象(安全令牌) 。AuthenticationSecurityContextHolder

例:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();

List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities());
updatedAuthorities.add(...); //add your role here [e.g., new SimpleGrantedAuthority("ROLE_NEW_ROLE")]

Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities);

SecurityContextHolder.getContext().setAuthentication(newAuth);

答案 2

谢谢,帮我很多忙!使用 ,我可以使用 getAllPrincipals() 将要修改的用户与会话中的当前活动用户进行比较。如果存在会话,我可以使用:expireNow()(from)强制重新进行身份验证,从而使他的会话无效。SessionRegistrySessionInformation

但是我不明白?securityContextPersistenceFilter

编辑:

// user object = User currently updated
// invalidate user session
List<Object> loggedUsers = sessionRegistry.getAllPrincipals();
for (Object principal : loggedUsers) {
    if(principal instanceof User) {
        final User loggedUser = (User) principal;
        if(user.getUsername().equals(loggedUser.getUsername())) {
            List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(principal, false);
            if(null != sessionsInfo && sessionsInfo.size() > 0) {
                for (SessionInformation sessionInformation : sessionsInfo) {
                    LOGGER.info("Exprire now :" + sessionInformation.getSessionId());
                    sessionInformation.expireNow();
                    sessionRegistry.removeSessionInformation(sessionInformation.getSessionId());
                    // User is not forced to re-logging
                }
            }
        }
    }
} 

推荐