如何编写自定义验证器
编辑本页如何编写自定义验证器
ob娱乐下载附赠Symfony许多的身份验证器第三方捆绑包也实现了更复杂的情况,如JWT和oAuth 2.0。然而,有时您需要实现一个还不存在的自定义身份验证机制,或者您需要自定义一个。在这种情况下,必须创建并使用自己的验证程序。
身份验证程序应该实现AuthenticatorInterface.你也可以扩展AbstractAuthenticator类的默认实现createToken ()
适合大多数用例的方法:
12 34 56 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/ / src /安全/ ApiKeyAuthenticator.php名称空间应用程序\安全;使用ob娱乐下载\组件\HttpFoundation\JsonResponse;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;使用ob娱乐下载\组件\安全\核心\身份验证\令牌\TokenInterface;使用ob娱乐下载\组件\安全\核心\异常\AuthenticationException;使用ob娱乐下载\组件\安全\核心\异常\CustomUserMessageAuthenticationException;使用ob娱乐下载\组件\安全\Http\身份验证\AbstractAuthenticator;使用ob娱乐下载\组件\安全\Http\身份验证\护照\徽章\UserBadge;使用ob娱乐下载\组件\安全\Http\身份验证\护照\护照;使用ob娱乐下载\组件\安全\Http\身份验证\护照\SelfValidatingPassport;类ApiKeyAuthenticator扩展AbstractAuthenticator{/** *在每个请求上调用,以决定是否应该为请求使用这个验证器。返回' false '将导致这个验证器*被跳过。* /公共函数支持(请求$请求):哦?保龄球{返回$请求->头->有(“X-AUTH-TOKEN”);}公共函数进行身份验证(请求$请求):护照{$apiToken=$请求->头->get (“X-AUTH-TOKEN”);如果(零= = =$apiToken) {//标记头为空,HTTP状态下认证失败//代码401 "未经授权"扔新CustomUserMessageAuthenticationException (“没有提供API令牌”);}返回新SelfValidatingPassport (新UserBadge ($apiToken));}公共函数onAuthenticationSuccess(请求$请求, TokenInterface$令牌、字符串$firewallName):哦?响应{//如果成功,让请求继续返回零;}公共函数onAuthenticationFailure(请求$请求, AuthenticationException$异常):哦?响应{$数据= (//你可能想先自定义或模糊消息“消息”= > strtr ($异常->getMessageKey (),$异常->getMessageData ())//或翻译此消息// $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())];返回新JsonResponse ($数据、响应::HTTP_UNAUTHORIZED);}}
提示
如果自定义验证程序是登录表单,则可以从AbstractLoginFormAuthenticator类来简化你的工作。
方法可以启用验证程序custom_authenticators
设置:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8
#配置/包/ security.yaml安全:#……防火墙:主要:custom_authenticators:-App \安全\ ApiKeyAuthenticator
提示
您可能希望您的验证程序实现AuthenticationEntryPointInterface
.这定义了发送给用户以开始身份验证的响应(例如,当他们访问受保护的页面时)。阅读更多入口点:帮助用户开始身份验证.
的authenticate ()
方法是验证程序中最重要的方法。它的工作是提取凭证(例如用户名和密码,或API令牌)从请求
对象并将其转换为证券护照(安全护照将在本文后面解释)。
在身份验证过程完成后,用户要么通过了身份验证,要么出现了错误(例如密码错误)。验证者可以定义在这些情况下会发生什么:
-
onAuthenticationSuccess(Request $ Request, TokenInterface $token, string $firewallName):
-
如果用户通过了身份验证,则使用经过身份验证的用户调用此方法
美元的令牌
.该方法可以返回响应(例如,将用户重定向到主页)。如果
零
返回时,请求像正常一样继续(即调用匹配登录路由的控制器)。这对于每个路由都由API密钥头保护的API路由非常有用。 -
onAuthenticationFailure(Request $ Request, AuthenticationException $exception):
-
如果一个
AuthenticationException
在身份验证期间抛出,则流程失败并调用此方法。这个方法可以返回一个响应(例如在API路由中返回401个未经授权的响应)。如果
零
返回时,请求像正常一样继续。这对于登录表单很有用,登录控制器再次运行时出现登录错误。如果你在使用登录节流,你可以检查一下
美元的例外
的实例。TooManyLoginAttemptsAuthenticationException(例如显示适当的信息)。谨慎:从不使用
异常- > getMessage ()
为AuthenticationException
实例。此邮件可能包含您不希望公开的敏感信息。相反,使用异常- > getMessageKey ()
而且异常- > getMessageData ()
如上面的完整示例所示。使用CustomUserMessageAuthenticationException如果要设置自定义错误消息。
提示
如果您的登录方法是交互式的,这意味着用户主动登录到您的应用程序,您可能希望您的身份验证程序实现InteractiveAuthenticatorInterface这样它就发送了一个InteractiveLoginEvent
安全护照
护照是一个对象,它包含了要进行身份验证的用户以及其他信息,比如是否应该检查密码或是否应该启用“记住我”功能。
默认的护照需要用户和某种“凭据”(例如密码)。
使用UserBadge将用户附在护照上。的UserBadge
需要用户标识符(例如用户名或电子邮件),用于加载用户使用用户提供者:
1 2 3 4
使用ob娱乐下载\组件\安全\Http\身份验证\护照\徽章\UserBadge;/ /……$护照=新护照(新UserBadge ($电子邮件),$凭证);
请注意
为防止用户标识符的最大长度为4096个字符会话存储泛洪攻击。
请注意
属性的第二个参数可以选择传递用户加载器UserBadge
.这个可调用对象接收userIdentifier美元
并且必须返回用户界面
对象(否则UserNotFoundException
抛出):
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/ / src /安全/ CustomAuthenticator.php名称空间应用程序\安全;使用应用程序\存储库\UserRepository;/ /……类CustomAuthenticator扩展AbstractAuthenticator{私人$userRepository;公共函数__construct(UserRepository$userRepository){$这->userRepository =$userRepository;}公共函数进行身份验证(请求$请求):护照{/ /……返回新护照(新UserBadge ($电子邮件,函数(字符串$userIdentifier){返回$这->userRepository->findOneBy ([“电子邮件”= >$userIdentifier]);}),$凭证);}}
默认支持以下凭据类:
- PasswordCredentials
-
这需要一个明文
美元的密码
方法进行验证为用户配置的密码编码器:1 2 3 4
使用ob娱乐下载\组件\安全\Http\身份验证\护照\凭证\PasswordCredentials;/ /……返回新护照(新UserBadge ($电子邮件),新PasswordCredentials ($plaintextPassword));
- CustomCredentials
-
允许自定义闭包检查凭证:
12 3 4 5 6 7 8 9 10 11 12 13 14 15
使用ob娱乐下载\组件\安全\核心\用户\用户界面;使用ob娱乐下载\组件\安全\Http\身份验证\护照\凭证\CustomCredentials;/ /……返回新护照(新UserBadge ($电子邮件),新CustomCredentials (//如果这个函数返回的不是' true ',则是credentials . properties//标记为无效。// $credentials参数等于该类的下一个参数函数($凭证,用户界面$用户){返回$用户->getApiToken () = = =$凭证;},//自定义凭证$apiToken));
自我验证护照
如果您不需要检查任何凭据(例如,当使用API令牌时),您可以使用SelfValidatingPassport.这个类只需要UserBadge
对象,可选地护照徽章.
护照徽章
的护照
还可选地允许您添加安全徽章.徽章在护照上附加更多的数据(以增加安全性)。默认情况下,支持的徽章如下:
- RememberMeBadge
-
当将此徽章添加到护照时,验证器表示支持remember me。是否真的记得我要看非凡
remember_me
配置。读如何添加“记得我”登录功能获取更多信息。 - PasswordUpgradeBadge
- 这用于在成功登录时自动将密码升级为新的散列(如果需要)。此徽章需要明文密码和密码升级器(例如用户存储库)。看到密码哈希和验证.
- CsrfTokenBadge
- 在身份验证期间自动验证此身份验证器的CSRF令牌。构造函数需要一个令牌ID(每个表单唯一)和CSRF令牌(每个请求唯一)。看到如何实施CSRF保护.
- PreAuthenticatedUserBadge
- 指示该用户是预先验证的(即在Symfony初始化之前)。ob娱乐下载这跳过了认证前用户检查器.
请注意
的PasswordUpgradeBadge
自动添加到护照,如果护照有PasswordCredentials
.
例如,如果你想将CSRF添加到你的自定义验证器中,你可以像这样初始化护照:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/ / src /服务/ LoginAuthenticator.php名称空间应用程序\服务;/ /……使用ob娱乐下载\组件\安全\Http\身份验证\AbstractAuthenticator;使用ob娱乐下载\组件\安全\Http\身份验证\护照\徽章\CsrfTokenBadge;使用ob娱乐下载\组件\安全\Http\身份验证\护照\徽章\UserBadge;使用ob娱乐下载\组件\安全\Http\身份验证\护照\护照;类LoginAuthenticator扩展AbstractAuthenticator{公共函数进行身份验证(请求$请求):护照{$密码=$请求->请求->get (“密码”);$用户名=$请求->请求->get (“用户名”);$csrfToken=$请求->请求->get (“csrf_token”);/ /……验证没有参数为空返回新护照(新UserBadge ($用户名),新PasswordCredentials ($密码), (新CsrfTokenBadge (“登录”,$csrfToken)));}}
护照属性
除了徽章,护照还可以定义属性,这允许authenticate ()
方法在护照中存储任意信息,以便从其他验证器方法(例如。createToken ()
):
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/ /……使用ob娱乐下载\组件\安全\Http\身份验证\护照\徽章\UserBadge;类LoginAuthenticator扩展AbstractAuthenticator{/ /……公共函数进行身份验证(请求$请求):护照{/ /……处理请求$护照=新SelfValidatingPassport (新UserBadge ($用户名), []);//设置自定义属性(例如scope)$护照->setAttribute (“范围”,$oauthScope);返回$护照;}公共函数createToken(护照$护照、字符串$firewallName):TokenInterface{//读取属性值返回新CustomOauthToken ($护照->getUser (),$护照->getAttribute (“范围”));}}