问题描述
我只是想更改内存中提供程序的默认 User
对象.默认的 User
对象是 Symfony\Component\Security\Core\User\User
.但是这个对象没有满足我的要求,所以我复制了那个对象并为我的要求添加了一些属性,然后将它命名为 InMemoryUser
并像下面这样使用它:
I'm just trying to change default User
object for in-memory provider. Default User
object is Symfony\Component\Security\Core\User\User
. But this object doesn't fill my requirements, so i copied that object and added some properties for my requirements then named it as InMemoryUser
and used it like following:
encoders:
App\Component\Security\Core\User\InMemoryUser: plaintext
然后在尝试运行该应用程序时出现以下错误.
Then i got the following error when tried to run the app.
No encoder has been configured for account "App\Component\Security\Core\User\InMemoryUser"
我在调查大约半小时后看到了这个问题.Symfony 默认调用 Symfony\Component\Security\Core\User\InMemoryUserProvider
并使用 Symfony\Component\Security\Core\User\User
对象来创建内存用户在 __construct
方法中.
I saw the problem after investigeting about half hour. Symfony is calling Symfony\Component\Security\Core\User\InMemoryUserProvider
by default and using Symfony\Component\Security\Core\User\User
object to create in-memory users in __construct
method.
然后我尝试覆盖默认的 InMemoryUserProvider
如下.
Then i tryed to override default InMemoryUserProvider
as following.
services:
App\Component\Security\Core\User\CustomInMemoryUserProvider:
decorates: security.user.provider.concrete.api_user_provider
arguments:
$users: [] # this should be contains in-memory users defined in the security.yaml but i dont know how to do that.
除了一个小问题外,这很好用,不会像 InMemoryUserProvider
那样注入 $users
.通常,$users
包含在 security.yaml
中定义的内存用户列表.
This works fine except a little problem, does not inject $users
like InMemoryUserProvider
. Normally, $users
contains in-memory user list defined in security.yaml
.
现在,我如何为我的 CustomInMemoryUserProvider
注入 $users
,这是更改 InMemoryProvider 的
?User
对象的好习惯吗?
Now, how can i inject $users
for my CustomInMemoryUserProvider
and is this a good practice to change User
object for InMemoryProvider
?
提前感谢您的回答.
顺便说一下,我正在使用 symfony 5.1
.
I'm using symfony 5.1
by the way.
推荐答案
我从来没有完全破解过正确装饰服务的奥秘,该服务的构造函数由 DI 扩展动态注入.
I have never quite cracked the mystery of properly decorating a service whose constructor gets injected dynamically by a DI extension.
但是,在这种情况下,您真正需要做的就是更改内存提供程序的类,这可以在内核中的编译器传递中完成:
However, in this case, all you really need to do is to change the class of the in memory provider which can be done in a compiler pass in your kernel:
# src\Kernel.php
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use App\User\InMemoryUserProvider;
class Kernel extends BaseKernel implements CompilerPassInterface
...
public function process(ContainerBuilder $container)
{
$id = 'security.user.provider.in_memory';
$container->getDefinition($id)->setClass(InMemoryUserProvider::class);
}
在测试时,我最初尝试扩展内存提供程序中的现有核心,但它使用了无法覆盖的私有方法.所以我只是重新实现了完整的界面
When testing this I originally tried to extend the existing core in memory provider but it uses a private method which can't be overridden. So I just re-implemented the complete interface
namespace App\User;
class InMemoryUserProvider implements UserProviderInterface
{
public function __construct(array $users)
{
dump($users); // Confirms get the users from security.yaml
}
public function loadUserByUsername(string $username)
{
// TODO: Implement loadUserByUsername() method.
echo "Get User {$username}\n";
}
确认它已按预期接线:
bin/console debug:container | grep UserProv
App\User\InMemoryUserProvider = App\User\InMemoryUserProvider
Symfony\Component\Security\Core\User\UserProviderInterface = alias for "security.user.provider.concrete.users_in_memory"
security.user.provider.concrete.users_in_memory = App\User\InMemoryUserProvider
security.user.provider.in_memory = App\User\InMemoryUserProvider
并发出一个命令只是为了验证它是否按预期工作:
And made a command just to verify it all worked as expected:
class UserProviderCommand extends Command
{
protected static $defaultName = 'user:provider';
private $userProvider;
public function __construct(UserProviderInterface $userProvider)
{
parent::__construct();
$this->userProvider = $userProvider;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
echo "User Provider: " . get_class($this->userProvider) . "\n";
$this->userProvider->loadUserByUsername('xxx');
return 0;
}
}
这篇关于更改内存中提供程序的默认用户对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!