FOSUserBundle与HWIOAuthBundle问题:自定义UserChecker在Facebook登录时失效
解决FOSUserBundle自定义UserChecker在HWIOAuthBundle登录时不生效的问题
我之前也踩过这个坑!FOSUserBundle的自定义UserChecker默认只会在表单登录的流程里被调用,而HWIOAuthBundle的OAuth登录走的是独立的认证逻辑,所以不会自动触发你的封禁检查。下面是几个亲测有效的解决思路:
确保防火墙配置中绑定UserChecker到OAuth流程
很多时候我们只在form_login的防火墙节点下配置了user_checker,但OAuth对应的防火墙规则里没加。你需要在security.yaml里把自定义UserChecker也加到OAuth相关的防火墙配置中:security: firewalls: main: form_login: provider: fos_userbundle user_checker: App\Security\UserChecker oauth: resource_owners: facebook: "/login/check-facebook" login_path: /login failure_path: /login oauth_user_provider: service: hwi_oauth.user.provider.fosub_bridge user_checker: App\Security\UserChecker # 给OAuth流程也绑定你的Checker监听HWIOAuthBundle的认证成功事件
HWIOAuthBundle在OAuth登录成功后会触发hwi_oauth.authentication.success事件,我们可以通过监听这个事件,手动调用UserChecker的封禁检查逻辑:- 创建事件监听器类:
namespace App\EventListener; use App\Security\UserChecker; use HWI\Bundle\OAuthBundle\Event\AuthenticationSuccessEvent; use Symfony\Component\Security\Core\Exception\AccountStatusException; class OAuthAuthenticationSuccessListener { private $userChecker; public function __construct(UserChecker $userChecker) { $this->userChecker = $userChecker; } public function onAuthenticationSuccess(AuthenticationSuccessEvent $event) { $user = $event->getUser(); try { // 调用你自定义的封禁检查逻辑 $this->userChecker->checkPostAuth($user); } catch (AccountStatusException $e) { // 抛出异常终止登录,或者跳转到封禁提示页 throw $e; } } }- 在
services.yaml中注册监听器:
services: App\EventListener\OAuthAuthenticationSuccessListener: arguments: ['@App\Security\UserChecker'] tags: - { name: kernel.event_listener, event: hwi_oauth.authentication.success, method: onAuthenticationSuccess }重写OAuth用户提供者的加载方法
如果你用的是FOSUBUserProvider作为OAuth用户提供者,可以重写它的loadUserByOAuthUserResponse方法,在加载用户后直接执行封禁检查:namespace App\Security; use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface; use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider; use Symfony\Component\Security\Core\Exception\AccountStatusException; class CustomOAuthUserProvider extends FOSUBUserProvider { private $userChecker; public function __construct(UserChecker $userChecker, $userManager, $properties) { parent::__construct($userManager, $properties); $this->userChecker = $userChecker; } public function loadUserByOAuthUserResponse(UserResponseInterface $response) { $user = parent::loadUserByOAuthUserResponse($response); try { $this->userChecker->checkPostAuth($user); } catch (AccountStatusException $e) { throw $e; } return $user; } }然后在
services.yaml替换默认的FOSUB服务:services: hwi_oauth.user.provider.fosub_bridge: class: App\Security\CustomOAuthUserProvider arguments: - '@App\Security\UserChecker' - '@fos_user.user_manager' - { facebook: facebook_id } # 替换成你的资源所有者配置检查UserChecker的方法覆盖完整性
确保你的自定义UserChecker同时实现了checkPreAuth和checkPostAuth方法,OAuth登录流程可能在不同阶段触发检查,checkPostAuth是认证成功后的关键检查节点,别漏掉它。
内容的提问来源于stack exchange,提问作者nass
相关产品推荐
相关产品推荐

