簡體   English   中英

Spring Security自定義身份驗證 - AuthenticationProvider與UserDetailsS​​ervice

[英]Spring Security Custom Authentication - AuthenticationProvider vs UserDetailsService

據我所知,當你想在Spring Security中進行自定義身份驗證時,你可以實現自定義AuthenticationProvider或自定義UserDetailsService

@Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth    
            //.authenticationProvider(authProvider)  // option 1
            .userDetailsService(userDetailsService); // option 2

    }

在AuthenticationProvider中,您可以檢查用戶名和密碼,並在其中返回自定義對象的Authentication

public Authentication authenticate(Authentication authentication){
        if (checkUsernameAndPassword(authentication)) {
            CustomUserDetails userDetails = new CustomUserDetails();
            //add whatever you want to the custom user details object
            return new UsernamePasswordAuthenticationToken(userDetails, password, grantedAuths);
        } else {
            throw new BadCredentialsException("Unable to auth against third party systems");
        }
    }

UserDetailsService您只獲得用戶名,當您返回自定義UserDeatails時,框架會檢查密碼。

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        CustomUserDetails user = new CustomUserDetails();
        //add whatever you want to the custom user details object
        return user;
    }

看起來兩者都可以產生類似的結果。 所以問題是有什么區別? 何時使用一對另一對?

答案在你的問題里面。 當您使用其他身份驗證系統,並且您自己的數據庫/數據模型中未提供密碼時,您必須使用AuthenticationProvider。 例如,我參與了一個客戶擁有集中認證系統(CAS)的項目,因此我的系統不知道密碼,我必須實現AuthenticationProvider並將給定的密碼發送給CAS,並按照它的答案。

但是在另一個系統中,我將密碼存儲在我的數據庫中,所以我所要做的就是實現UserDetailsS​​ervice並檢查用戶是否存在於我的數據庫中,spring-security必須完成剩下的工作。

從Spring安全文檔開始, https://docs.spring.io/spring-security/site/docs/5.0.0.RC1/reference/htmlsingle/#overall-architecture

關於UserDetailsS​​ervice經常會有一些混亂。 它純粹是用戶數據的DAO,除了將數據提供給框架內的其他組件之外,不執行任何其他功能。 特別是,它不會對用戶進行身份驗證,這是由AuthenticationManager完成的。 在許多情況下,如果您需要自定義身份驗證過程,則直接實現AuthenticationProvider會更有意義。

AuthenticationProvider和UserDetailsS​​ervice具有不同的用途。

AuthenticationProvider驗證(比較)用戶(請求)提供的用戶名和密碼與系統用戶(這可以是任何系統,如DB維護注冊用戶列表)

UserDetailsS​​ervice實現的責任是獲取與用戶提供的用戶名匹配的系統用戶詳細信息。 這里只是獲取具有相同用戶名的用戶,並且不告訴應用程序認證是成功還是失敗。

示例:Spring提供以下作為默認設置,以根據數據庫驗證用戶詳細信息

  • AuthenticationProvider - DaoAuthenticationProvider擴展AbstractUserDetailsAuthenticationProvider,通過傳遞用戶名,Authentication對象來調用authenticate方法
  • UserDetailsS​​ervice - JdbcDaoImpl
  • 認證流程
  1. DaoAuthenticationProvider的職責是驗證從數據庫用戶請求獲得的用戶名和密碼。
  2. 為了獲得相應的數據庫用戶,它要求UserDetailsS​​ervice Implementataion JdbcDaoImpl從數據庫獲取一個UserDetail對象,其名稱與請求username相同。這里JdbcDaoImpl只是從系統中獲取UserDetails對象。它將發送回在DB中找到的用戶或發送異常找不到該用戶。
  3. 如果在DB中找到用戶詳細信息,則DaoAuthenticationProvider繼續檢查請求用戶密碼,並且DB找到用戶密碼,否則驗證失敗。
  4. DaoAuthenticationProvider將根據JdbcDaoImpl響應來響應用戶是否經過身份驗證。

看看這里更好地理解它:

AuthenticationProvider - DaoAuthenticationProvider擴展AbstractUserDetailsAuthenticationProvider

UserDetailsS​​ervice - JdbcDaoImpl

UserDetails - 用戶

這兩者是相關的,但是被Spring Security故意分開。 如果企業有多個系統,UserDetailsS​​ervice將提供您的特定系統所擁有的特定用戶信息,即使身份驗證可能由另一個系統執行。 在一個簡單的系統中,它們可以組合在一起。 例如,數據庫調用將驗證用戶名/密碼並檢索該用戶的所有電子郵件,ID等。

根據Spring Security Reference: http//docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#getting-started

關於UserDetailsS​​ervice經常會有一些混亂。 它純粹是用戶數據的DAO,除了將數據提供給框架內的其他組件之外,不執行任何其他功能。 特別是,它不會對用戶進行身份驗證,這是由AuthenticationManager完成的。 在許多情況下,如果您需要自定義身份驗證過程,則直接實現AuthenticationProvider會更有意義。

暫無
暫無

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

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