2016-11-03 79 views
0

我正在創建一個Spring Boot Web應用程序,它將充當我的用戶的登錄網站。通過REST API在幕後,它使用OpenAM驗證憑證並創建會話令牌。我期望該令牌將用於管理此登錄網站以及我們爲用戶提供的所有其他網站(單點登錄)的會話。春季安全自定義登錄網站與第三方會話Cookie

我想SpringBoot應用程序是無狀態的。這使得部署更容易。雖然該網站應該是無國籍的,但顯然我們仍然保持OpenAM的會話狀態。

我在如何配置Spring安全性以使cookie代表Spring安全認可的有效會話而苦苦掙扎。當我使應用程序成爲無狀態時,它會導致各種CSRF保護問題,因爲它認爲我們正在使用cookie中的每個有OpenAM會話標記的請求重新進行身份驗證,並創建一個新的CSRF標頭(以防止會話受到保護固定)。

我對我的身份驗證類型使用PreAuthenticationToken。我應該使用RembemberMeAuthenticationToken嗎?我是否需要引入新的SessionAuthenticationStrategy?理想情況下,只有實際的登錄POST使Spring Security認爲創建了新會話。對於所有具有會話cookie的後續請求,它應該像通過身份驗證一樣讓它通過。 (我將在每次請求時用OpenAM驗證令牌)

想法? Andrew

回答

0

我創建了一個使用ForgeRock會話標記和默認Spring Security HttpSession的混合站點。爲了提供CSRF和會話劫持保護,創建完全無會話的應用程序非常具有挑戰性。

因此,我的應用程序利用Spring會話來提供CSRF和會話劫持投影,並且還充當緩存。 Spring會話持續30秒,在此期間,所有請求都使用存儲的主體信息,並且不需要查詢ForgeRock來驗證它。 30秒後,Spring會話過期並重新驗證ForgeRock會話並從OpenAM獲取更新的主要信息。

我在Spring Security應用程序中實現了一些鉤子來啓用此功能。我使用Spring Boot,Spring Security和Java配置方式將它們連接在一起。

  • 我用我自己的OpenAmCookieAuthentication過濾器替換了AbstractPreAuthenticatedProcessingFilter過濾器。在doFilter()方法中,它檢查HttpSession的持續時間(如果存在)。如果長於'x'秒,則會話失效。這會強制未來的過濾器重新驗證OpenAM cookie並獲取OpenAM主體信息。
  • 我用自己的過濾器替換了UsernamePasswordAuthenticationFilter過濾器。要清楚,我沒有在這裏實現我自己的過濾器,我只是配置了UsernamePasswordAuthenticationFilter實例。我設置了自己的定製成功和失敗處理程序
    • 我創建了自己的成功處理程序,它在成功通過OpenAM進行身份驗證時設置OpenAM會話cookie。它擴展了SavedRequestAwareAuthenticationSuccessHandler
    • 我創建了自己的失敗處理程序來處理失敗的登錄,這些失敗的登錄清除了cookie。它擴展ExceptionMappingAuthenticationFailureHandler
  • 覆蓋authenticationManagerBean()。它仍然使用ProviderManager類,但我通過了我自己的身份驗證提供程序列表
    • 創建一個實現AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken>接口的UserDetailsService。當有需要驗證的OpenAM會話令牌時(在30秒後Spring會話過期後),使用它
    • 創建實現AuthenticationProvider接口的驗證提供程序。這在標準登錄過程中用於使用OpenAM驗證用戶憑證。

最後,因爲我不能讓應用程序完全無狀態的,我使用的是嵌入式Tomcat實例來實現簡單的會話複製。此實現受此帖的啓發:enter link description here