我正在使用Spring Security通过OpenID进行身份验证的应用程序。当用户登录时,一些权限会加载到他的会话中。
我有完全权限的用户,可以修改其他用户的权限(撤销,添加角色)。我的问题是,如何动态更改用户会话权限?(不能使用 SecurityContextHolder,因为我想更改另一个用户会话)。
简单的方法:使用户会话无效,但如何?更好的方法:用新的权限刷新用户会话,但如何?
我正在使用Spring Security通过OpenID进行身份验证的应用程序。当用户登录时,一些权限会加载到他的会话中。
我有完全权限的用户,可以修改其他用户的权限(撤销,添加角色)。我的问题是,如何动态更改用户会话权限?(不能使用 SecurityContextHolder,因为我想更改另一个用户会话)。
简单的方法:使用户会话无效,但如何?更好的方法:用新的权限刷新用户会话,但如何?
7条答案
按热度按时间zpqajqem1#
如果您需要动态更新登录用户的权限(当这些权限发生变化时,无论出于何种原因),而不必注销并登录,您只需要在Spring
SecurityContextHolder
中重置Authentication
对象(安全令牌)。范例:
字符串
i1icjdpr2#
谢谢,帮了我很多!使用
SessionRegistry
,我可以使用getAllPrincipals()来比较要修改的用户和会话中当前活动的用户。如果会话存在,我可以使用:MyReNow()(来自SessionInformation
)来强制重新认证他的会话。但我不明白
securityContextPersistenceFilter
的用处?编辑:
字符串
ffdz8vbo3#
如果有人还在研究如何更新另一个用户的权限而不强制该用户重新进行身份验证,您可以尝试添加一个重新加载身份验证的拦截器,这将确保您的权限始终得到更新。
但是,由于额外的拦截器,会有一些性能影响(例如,如果从数据库获取用户角色,则会针对每个HTTP请求查询它)。
字符串
此特定实现使用OAuth2(
OAuth2AuthenticationToken
),但您也可以改用UsernamePasswordAuthenticationToken
。现在,将拦截器添加到配置中:
型
I also made an article about this的一个。
irlmq6kh4#
关键点-您应该能够访问用户
SecurityContext
s。如果你是在servlet环境中,并且在你的
securityContextPersistenceFilter
中使用HttpSession
作为securityContextRepository
,那么它可以用spring的SessionRegistry
来完成。为了强制用户重新认证(这应该比静默权限撤销更好),使他的HttpSession
无效。不要忘记将HttpSessionEventPublisher
添加到web.xml中字符串
如果你使用的是线程本地
securityContextRepository
,那么你应该在springSecurityFilterChain
中添加自定义过滤器来管理SecurityContext
的注册表。要做到这一点,你必须使用普通beanspringSecurityFilterChain
配置(没有security
命名空间快捷方式)。使用带有自定义过滤器的普通bean配置,你将完全控制身份验证和授权。有些链接,它们不能完全解决你的问题(没有OpenID),但可能有用:
ffvjumwh5#
我有一个非常具体的例子,我使用Redis来跟踪用户与https://github.com/spring-projects/spring-session的会话。然后当管理员为用户添加一些角色时,我在Redis中找到用户会话并替换
principal
和authorities
,然后保存会话。字符串
smdncfj36#
我使用TwiN给出的答案,但我创建了一个控制变量(users_to_update_roles)来减少性能影响。
字符串
在我的控制器中,我添加角色更新的用户
型
pxyaymoc7#
代码:
字符串