2013-08-19 54 views
0

在Symfony的文檔中,我理解用戶提供者和認證提供者應如何工作。我嘗試實現我自己的用戶和/或身份驗證提供程序。我還沒有完全得到,是如何比較/在哪裏檢查系統內的密碼。Symfony2:用戶/驗證提供者;密碼檢查

在文檔[1]中,我可以看到,如果用戶存在,用戶提供程序將返回一個用戶對象。不過,我可以看到,如果用戶已經發現,用戶在這個例子與

返回
return new WebserviceUser($username, $password, $salt, $roles); 
  1. 問題是:爲什麼是用戶對象的密碼返回這裏。
  2. 問題:如何檢索這個班級的密碼?這不是驗證提供者的任務嗎?如果是這樣,那麼如何檢查那裏的密碼?

肯定有一個用例,這個模型是有道理的,但暫時我沒有看到它。也許這裏有人有背景向我解釋這一點。

背景:我想使用LDAP進行身份驗證。因此,我的第一種方法是創建一個用戶提供者,該用戶提供者匿名檢查用戶是否通過ldap搜索存在,如果是,則嘗試對其進行身份驗證。問題是,我不能用密碼返回一個用戶對象(但也包含其他屬性,我只有在用戶已經通過身份驗證時才能獲得)。然後用戶將被存儲/緩存在本地數據庫中,用戶特定的設置和屬性也將被保存。

[1] http://symfony.com/doc/current/cookbook/security/custom_provider.html#create-a-user-provider

回答

3

安全系統確實是壓倒性的,它是很難知道從哪裏開始。我懷疑有可能已經有ldap捆綁(提示),但它是更有趣的做你自己的。

瞭解標準form_login防火牆的實現方式很有幫助。認證供應商減少到只有兩個方法:

namespace Symfony\Component\Security\Core\Authentication\Provider; 

class DaoAuthenticationProvider extends UserAuthenticationProvider 
{ 
    private $encoderFactory; 
    private $userProvider; 

protected function retrieveUser($username, UsernamePasswordToken $token) 
{ 
    try { 
     $user = $this->userProvider->loadUserByUsername($username); 

protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token) 
{ 
     if (!$this->encoderFactory->getEncoder($user)->isPasswordValid($user->getPassword(), $presentedPassword, $user->getSalt())) { 
      throw new BadCredentialsException('The presented password is invalid.'); 

所以登錄表單已經提交,用戶填寫用戶名和密碼,按下登錄鍵,form_login防火牆攔截login_check要求,確實都挺但最終會調用authenticationProvider.retrieverUser,然後調用userProvider.loadUserByUsername。

您的ldap用戶提供程序將對用戶名進行ldap搜索。如果沒有找到,那麼你拋出一個UserNotFoundException。如果找到了用戶,那麼你會包裝任何有用的信息並返回一個用戶對象。密碼在這一點上是無關緊要的。

發生了更多的奇蹟,並最終使用用戶對象從用戶提供程序返回的任何用戶對象調用authenticationProvider.checkAuthentication。在這一點上,您將使用您的ldap服務對用戶進行身份驗證(綁定)。用戶鍵入到登錄表單中的明文密碼可通過$ presentedPassword獲取。

一旦你有一個認證用戶,然後事情變得有點朦朧。你提到了在本地數據庫中緩存的東西。您可能最終必須重寫authenticationProvider.authenticate方法才能正確構建經過身份驗證的令牌。你可能需要訓練你的userProvider.refreshUser與你的本地緩存進行交談。在執行ldap搜索之前,您甚至可能需要使用userProvider.loadUserByUsername來檢查本地緩存。這些都是針對您的設計的所有細節。

您可以使用參數密鑰security.authentication.provider.dao.class在form_login防火牆內指向您自己的身份驗證提供程序類。這反過來會讓你獲得大部分(可能全部)的ldap功能,而無需構建完整的防火牆包。

玩得開心。

+0

謝謝。這是我正在尋找的解釋。我知道我必須重寫一些方法/類。由於我們的要求,存在的LDAP捆綁包至今仍在使用中,它們將由自己的捆綁包替換。 – christoph

+0

(Symfony 2.6)有一個問題,如果我使用LoginModel(用戶名,密碼)和LoginType(構建這些字段,命名更改爲...),您可以告訴如何獲取用戶和密碼,請求存儲在哪裏在我的類LdapAuthenticator實現SimpleFormAuthenticatorInterface之前,在進入authenticateToken(TokenInterface $ token,UserProviderInterface $ userProvider,$ providerKey)之前,Token與symfony的約定(_username,_password)不同。謝謝。 –

+0

@Felix - 可能最好開始一個新的問題。我不明白你在問什麼。 – Cerad