安全系統確實是壓倒性的,它是很難知道從哪裏開始。我懷疑有可能已經有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功能,而無需構建完整的防火牆包。
玩得開心。
謝謝。這是我正在尋找的解釋。我知道我必須重寫一些方法/類。由於我們的要求,存在的LDAP捆綁包至今仍在使用中,它們將由自己的捆綁包替換。 – christoph
(Symfony 2.6)有一個問題,如果我使用LoginModel(用戶名,密碼)和LoginType(構建這些字段,命名更改爲...),您可以告訴如何獲取用戶和密碼,請求存儲在哪裏在我的類LdapAuthenticator實現SimpleFormAuthenticatorInterface之前,在進入authenticateToken(TokenInterface $ token,UserProviderInterface $ userProvider,$ providerKey)之前,Token與symfony的約定(_username,_password)不同。謝謝。 –
@Felix - 可能最好開始一個新的問題。我不明白你在問什麼。 – Cerad