簡體   English   中英

具有數據庫角色的 Spring Security SAML

[英]Spring Security SAML with roles from database

我正在嘗試將 SAML SSO 集成到使用 Spring Security 的現有應用程序中,用戶、組和角色/權限存儲在 MySQL 數據庫中。 該應用程序當前使用<security:jdbc-user-service>從數據庫獲取用戶和角色。 有問題的 IDP 僅提供唯一的用戶名和電子郵件地址作為屬性,因此應用程序仍然必須存儲與每個用戶本身相關聯的組和角色(據我所知)。

因此,我嘗試通過上下文配置和自定義SAMLUserDetailsServicejdbc-user-servicesamlAuthenticationProvider掛鈎,從而同時使用 SAML 和數據庫。

這是我的applicationContext.xml的相關部分:

<bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider">
    <property name="userDetails" ref="customUserDetailService" />
</bean>
<bean id="customUserDetailService" class="org.myapp.CustomUserDetailsService">
    <property name="jdbcUserService" ref="jdbcUserDetailService" />
</bean>

<bean id="jdbcUserDetailService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="dataSource" ref="dataSource" />
    <property name="usersByUsernameQuery" value="select username,username as password,enabled from person where username=?" />
    <property name="authoritiesByUsernameQuery" value="select u.username, p.name as authorities 
                from person u, group g, group_permissions up, permission p 
                where u.group = g.id and g.id = up.group and up.permissions = p.id and  
                u.username=?" />
</bean>

這是CustomUserDetailsService的相關部分:

public class CustomUserDetailsService implements SAMLUserDetailsService {

    private JdbcDaoImpl jdbcUserService;

    @Override
    public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException {

        UserDetails user = null;
        String username = credential.getAttributeAsString("urn:mace:dir:attribute-def:cn");

        try {
            user = jdbcUserService.loadUserByUsername(username);
        } catch (UsernameNotFoundException e) {
            System.out.println("User not found in DB");
            // TODO
        }

        return user;
    }

    @Autowired
    public void setJdbcUserService(JdbcDaoImpl jdbcUserService) {
        this.jdbcUserService = jdbcUserService;
    }

    public JdbcDaoImpl getJdbcUserService() {
        return jdbcUserService;
    }
}

我的問題是:以這種方式使用 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl 是個好主意嗎?

我認為從數據庫中檢索角色的官方 Spring Security 實現 (JdbcDaoImpl) 比我自己想出的維護得更好、更靈活且沒有錯誤。

我的第二個問題是:使用select username, username as password以某種方式在應用程序中產生安全問題嗎?

由於我的應用程序永遠不會看到密碼(因為用戶只在 IDP 輸入它),我必須用查詢中的某些內容替換它。 我應該注意使這件事難以猜測還是無論如何都不會重新使用 UserDetails 中的密碼?

1. 這是一個好主意和/或它的用途嗎?

是的,您可以在 spring 中擁有自定義用戶對象並填充用戶詳細信息。

2.使用選擇用戶名,用戶名作為密碼會在應用程序中以某種方式產生安全問題嗎?

不,Spring SAML 不希望用戶密碼存儲在用戶對象中(而 saml 響應將由 spring 驗證)。 spring 將單獨驗證用戶名和權限。 我建議您只在用戶對象中設置 username 和 Granted Authorities 。

考慮如下圖:

基於 SAML 的 AuthN

它描述了基於 SAML 的身份驗證過程的所有典型步驟。

  • 請求受保護資源的用戶將從服務提供者(依賴方)重定向到第三方身份提供者。
  • 用戶在身份提供者上執行身份驗證(即同時提供用戶名/密碼、OTP、PIN 碼等)。
  • 如果身份驗證成功,身份提供者會將 SAML 信封發送回服務提供者。 它包含存儲在 SAML 斷言中的用戶個人資料信息(名字、姓氏、電子郵件、電話號碼、組織等),根據雙方之間的屬性發布協議。 用戶也被重定向回服務提供商。

此時,由於雙方之間的信任關系,IdP 正在為用戶身份提供擔保。 您不再需要詢問密碼,因為 AuthN 過程已完成。 此時您通常需要的是管理資源訪問控制的信息,即授權 (AuthZ)。 通常使用角色模型 (RBAC) 執行 AuthZ:

The user "jdoe" is authenticated.
The user "jdoe" has "StandardUser" as role.
The resource A is available only for "Administrator".
The user "jdoe" is not authorised to access to the resource A.

同樣:

The user "jdoe" is authenticated.
The user "jdoe" has "StandardUser" as role.
The resource B is available only for "StandardUser".
The user "jdoe" is authorised to access to the resource B.

考慮到所有用戶的角色都存儲在本地數據庫中,您必須在執行數據訪問時檢索這些信息以匹配身份和角色。

所以:

這是一個好主意和/或它的使用方式嗎?

方法loadUserBySAML應該識別 SAML 斷言中數據引用的用戶的本地帳戶,並返回描述用戶的UserDetails對象。 此時,您還應該根據某個用戶在您的應用程序域中的角色,為其授予適當的權限。 本地數據檢索實現由您決定。 您可以使用標准訪問,對您的數據庫執行直接查詢,或者根據 JPA 規范(請參閱Spring Data ),通過使用 ORM 來實現現代數據訪問模型。

使用選擇用戶名、用戶名作為密碼會以某種方式在應用程序中產生安全問題嗎?

如前所述,您不需要對應用程序執行用戶憑據驗證,因為您使用的是基於 SAML 的身份驗證。 SSO 實際上設計為不共享關鍵信息,例如密碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM