2017-01-05 27 views
0

我們有一個場景,我們有一系列應用程序,都使用spring-session(w/Redis),用戶可以多次登錄以訪問不同的應用程序。多個應用程序,相同會話和更新角色

如果管理員修改用戶添加新角色(例如,訪問新應用)(GrantedAuthority),我們需要將其反映到所有用戶活動會話中。

問題是,我認爲SecurityContextHolder對SecurityContext使用ThreadLocal存儲(它繼而保存GrantedAuthorities)。

我試着與會話存儲庫進行交互,並使用它來更新會話信息,但由於上述TL存儲,它不會在應用程序中反映出來。

有沒有一種常見的模式/策略以這種方式傳播更新角色信息?

謝謝。

+0

只是爲了澄清一下,您的所有應用程序是否都使用相同的會話信息通過共享相同的Redis會話存儲?或者你在使用OAuth2等集中式認證解決方案嗎? –

+0

我們正在使用相同的共享Redis會話存儲。 –

回答

0

最簡單的(和IMO首選的)解決方案將強制用戶重新進行身份驗證,並因此創建一個新的Authentication,然後包含新的GrantedAuthority集合。您可以使用Spring Session的FindByIndexNameSessionRepository獲取給定用戶的所有會話,然後刪除它們。這將生成SessionDeletedEvent,這將傳播到您的所有應用程序(因爲它們共享相同的Redis會話存儲)。

如果您必須保留活動會話,事情會更加複雜。您仍然可以使用FindByIndexNameSessionRepository獲取給定用戶的所有會話,但是您需要從每個會話中提取SecurityContext,並使用新權限更新其Authentication,並確保在共享會話存儲的所有應用上完成。爲此,您需要在ProviderManager上禁用eraseCredentialsAfterAuthentication,以便您可以使用新權限重新創建Authentication(您需要原始Authentication的憑據)。爲確保SecurityContext在所有應用中更新,您必須採用某種發佈 - 訂閱機制來觸發該代碼的執行。

正如您所見,第一個解決方案更簡單,更安全(因爲您不需要禁用eraseCredentialsAfterAuthentication)。同樣值得注意的是,如果Spring Session支持HttpSessionAttributeListener(請參閱this ticket),那麼第二種解決方案會更簡單,因爲它將覆蓋發佈 - 訂閱機制部分。

+0

感謝您的2種選擇。欣賞它。 –

相關問題