我们有一个场景,其中我们有一系列应用程序,都使用spring-session (w/Redis),其中用户可以多次登录以访问不同的应用程序。
如果管理员修改用户以添加新角色(例如,访问新应用程序)( GrantedAuthority),我们需要在所有用户的活动会话中反映出来。
我认为问题在于,SecurityContextHolder使用ThreadLocal存储来存储SecurityContext (而GrantedAuthorities又保存在for中)。
我尝试与会话存储库交互,并使用它来更新会话信息,但由于上面的TL存储,它不会在应用程序中反映出来。
是否有以这种方式传播角色信息更新的通用模式/策略?
谢谢。
发布于 2017-01-10 02:34:58
最简单(也是IMO首选的)解决方案是强制您的用户重新进行身份验证,从而创建一个新的Authentication,然后包含一个新的GrantedAuthority集合。您可以使用Spring Session的FindByIndexNameSessionRepository获取给定用户的所有会话,然后将其删除。这将生成SessionDeletedEvent,它将传播到您的所有应用程序(因为它们共享相同的Redis会话存储)。
如果你必须保留活动会话,事情就复杂多了。您仍然可以使用FindByIndexNameSessionRepository获取给定用户的所有会话,但是您需要从每个会话中提取SecurityContext,并使用新的授权更新其Authentication,并确保在共享会话存储的所有应用程序上完成此操作。为此,您需要在您的ProviderManager上禁用eraseCredentialsAfterAuthentication,以便可以使用新的授权重新创建Authentication (您需要来自原始Authentication的凭证)。为了确保所有应用程序上的SecurityContext都得到更新,您必须使用某种发布-订阅机制来触发代码的执行。
正如您所看到的,第一个解决方案更简单,也更安全(因为您不需要禁用eraseCredentialsAfterAuthentication)。同样值得注意的是,如果Spring Session支持HttpSessionAttributeListener (请参阅this ticket),那么第二种解决方案会更简单,因为这将涵盖发布-订阅机制部分。
https://stackoverflow.com/questions/41486748
复制相似问题