我正在尝试制作一个How to create a custom Authentication Provider,在完整阅读并查看Symfony代码之后,我认为只需创建一个Factory,身份验证提供程序并使用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”满足我的需求?
答案 0 :(得分:0)
您将字符串 arguments: [""]
作为服务构造函数的第一个参数传递。
这就是__construct(UserProviderInterface $userProvider)
中的typehint失败的原因。
正确注入UserProviderInterface
,异常将消失。