更改内存中提供程序的默认用户对象 [英] Changing default User object for in-memory provider

查看:38
本文介绍了更改内存中提供程序的默认用户对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想更改内存中提供程序的默认 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;
    }
}

这篇关于更改内存中提供程序的默认用户对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆