【问题标题】:Symfony2 ContextErrorException in Custom Authentication Provider自定义身份验证提供程序中的 Symfony2 ContextErrorException
【发布时间】:2014-01-31 18:01:53
【问题描述】:

我正在尝试创建一个How to create a custom Authentication Provider,在完整阅读并查看了 Symfony 代码之后,我认为只需创建一个工厂、身份验证提供程序并使用 symfony 默认类就足够了,但实际上我是遗漏了一些东西,我收到了这个错误

ContextErrorException: Catchable Fatal Error: Argument 1 passed to Acme\DemoBundle\Provider\MyProvider::__construct() must implement interface Symfony\Component\Security\Core\User\UserProviderInterface, string given, called in D:\wamp\www\sf2ldap\app\cache\dev\appDevDebugProjectContainer.php on line 1383 and defined in D:\wamp\www\sf2ldap\src\Acme\DemoBundle\Provider\MyProvider.php line 20

工厂

namespace Acme\DemoBundle\Factory;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory;

class MyFactory extends AbstractFactory
{

    public function getPosition()
    {
        return 'form';
    }

    public function getKey()
    {
        return 'kstr';
    }

    protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId)
    {

        $providerId = 'security.authentication.provider.kstr.' . $id;
        $container
                ->setDefinition($providerId, new DefinitionDecorator('kstr.security.authentication.provider'))
                ->replaceArgument(0, new Reference($userProviderId));
        return $providerId;
    }

    protected function getListenerId()
    {
        return 'security.authentication.listener.form';
    }

}

我的提供者

namespace Acme\DemoBundle\Provider;

use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class MyProvider implements AuthenticationProviderInterface
{

    private $_userProvider;

    public function __construct(UserProviderInterface $userProvider)
    {
        $this->_userProvider = $userProvider;
    }

    public function authenticate(TokenInterface $token)
    {
        try
        {
            $user = $this->_userProvider->loadUserByUsername($token->getUsername());
            //custom auth steps
            $token = new UsernamePasswordToken(
                    $token->getUsername(), null, $token->getProviderKey(), $user->getRoles()
            );
            return $token;
            }
        } catch (\Exception $exc)
        {
            throw new AuthenticationException('Invalid username or password. ', 0, $e);
        }
        throw new AuthenticationException('Invalid username or password asdfasd');
    }

    public function supports(TokenInterface $token)
    {
        return $token instanceof UsernamePasswordToken;
    }

}

services.yml

services:
    kstr.security.authentication.provider:
        class:  Acme\DemoBundle\Provider\MyProvider
        arguments: [""]

security.yml

security:
    encoders:
        Acme\DemoBundle\Entity\SecureUser: plaintext
    providers:
        multiples:
            chain:
                providers: [entity_provider, ldap]
        entity_provider:
          entity: { class: AcmeDemoBundle:SecureUser, property: username }
        ldap:
          id: kstr.security.authentication.provider

    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        login:
            pattern:  ^/demo/secured/login$
            security: false

        secured_area:
            pattern:    ^/demo/secured/
            kstr: 
                check_path: _security_check
                login_path: _demo_login
                provider: ldap
            logout:
                path:   _demo_logout
                target: _demo

需要一些帮助来解决这个问题,我在这里缺少什么?即使默认的“security.authentication.listener.form”满足我的需求,我是否需要创建自定义侦听器?

【问题讨论】:

    标签: php symfony authentication


    【解决方案1】:

    您将 字符串 arguments: [""] 作为第一个参数传递给服务的构造函数。

    这就是__construct(UserProviderInterface $userProvider) 中的类型提示失败的原因。

    正确注入UserProviderInterface,异常就会消失。

    【讨论】:

    • createAuthProvider 上的 MyFactory 不应该这样做吗?注入,或者我正在导入service.yml 到很快?我在config.yml
    • 您应该将您的父服务kstr.security.authentication.provider 声明为抽象服务或使用setter 注入而不是构造函数注入...否则将在替换参数之前创建父服务。请阅读文档章节Managing Common Dependencies with Parent Services
    猜你喜欢
    • 2012-02-22
    • 2013-03-16
    • 2012-04-05
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 2013-02-07
    • 2015-11-06
    • 1970-01-01
    相关资源
    最近更新 更多