php - 更改内存提供程序的默认用户对象
问题描述
我只是想更改User
内存提供程序的默认对象。默认User
对象是Symfony\Component\Security\Core\User\User
. 但是这个对象不能满足我的要求,所以我复制了那个对象并为我的要求添加了一些属性,然后将它命名为InMemoryUser
并使用它,如下所示:
encoders:
App\Component\Security\Core\User\InMemoryUser: plaintext
然后在尝试运行该应用程序时出现以下错误。
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
方法中创建内存用户。
然后我尝试InMemoryUserProvider
如下覆盖默认值。
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.
这工作正常,除了一个小问题,不会$users
像InMemoryUserProvider
. 通常,$users
包含定义在内存中的用户列表security.yaml
。
现在,我如何$users
为我注入,CustomInMemoryUserProvider
这是更改User
对象的好习惯InMemoryProvider
吗?
提前感谢您的回答。
顺便说一句,我正在使用symfony 5.1
。
解决方案
我从来没有完全破解正确装饰其构造函数由 DI 扩展动态注入的服务的奥秘。
但是,在这种情况下,您真正需要做的就是更改内存提供程序的类,这可以在内核中的编译器传递中完成:
# 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);
}
在测试这个时,我最初尝试扩展内存提供程序中的现有核心,但它使用了一个不能被覆盖的私有方法。所以我只是重新实现了完整的界面
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
并发出一个命令来验证它是否按预期工作:
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;
}
}
推荐阅读
- c++ - 进入 C++ 第 17 章问题 4 - 二叉树
- javascript - 使用 dangerouslySetInnerHTML 在 React 中插入完整的 HTML
- c++ - 为什么我的结构在包含字符串时会崩溃?
- jenkins - 由于读取超时,Jenkins 插件管理器无法安装/更新插件
- reactjs - 粘贴文件在剪贴板中不起作用(更新->关于剪贴板权限)
- c# - EF Core (3.1) 工具:有没有办法将数据库降级到之前的迁移?
- python - 已安装 lxml 但仍有“ImportError: lxml not found, please install it”错误
- android - Unity - 2019.3 Mobile Android APK 加载失败
- java - 关系实体的 Spring Data Neo4j 存储库
- ruby-on-rails - 不能为隐藏属性输入标签的值赋值