安全用户提供商
编辑本页警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 5.2,现已不再维护。
读本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。
安全用户提供商
用户提供者是与Symfony Security相关的PHP类,它有两个任务:ob娱乐下载
- 从会话中重新加载User
-
在每个请求的开始(除非您的防火墙
无状态的
), ob娱乐下载Symfony加载用户
对象。为了确保它没有过期,用户提供程序会“刷新它”。例如,Doctrine用户提供程序查询数据库中的新数据。ob娱乐下载Symfony然后检查用户是否已经“更改”,如果已经更改,则取消对用户的身份验证(请参阅安全用户提供商). - 为某些特性加载用户
- 一些特性,比如用户模拟,记得我还有很多内置的身份验证提供者,使用用户提供程序通过其“用户名”(或电子邮件,或任何你想要的字段)加载一个user对象。
ob娱乐下载Symfony有几个内置的用户提供者:
- 实体用户提供商(从数据库中加载用户);
- LDAP用户提供者(从LDAP服务器加载用户);
- 内存用户提供商(从配置文件中加载用户);
- 连锁用户提供商(将两个或多个用户提供程序合并为一个新的用户提供程序)。
内置的用户提供程序涵盖了大多数应用程序的所有需求,但您也可以创建自己的用户提供程序定制用户提供程序.
实体用户提供商
这是传统web应用程序最常见的用户提供程序。用户存储在数据库中,由用户提供程序使用学说要检索它们:
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#配置/包/ security.yaml安全:#……提供者:用户:实体:#代表用户的实体的类类:“应用程序实体\ \用户”#要查询的属性,例如用户名,电子邮件等属性:“用户名”#可选:如果你使用多个Doctrine实体# managers,这个选项定义了使用哪个# manager_name: '客户'#……
的供应商
节创建名为用户
知道如何从你的查询应用实体\ \用户
实体用户名
财产。您可以为用户提供程序选择任何名称,但建议选择描述性名称,因为稍后将在防火墙配置中使用。
使用自定义查询加载用户
的实体
提供者只能查询一个具体的属性指定的财产
配置的关键。如果你想在这方面有更多的控制-例如,你想通过电子邮件
或用户名
,你可以通过使你的UserRepository
实现UserLoaderInterface.该接口只需要一个方法:loadUserByUsername(用户名)
:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/ / src /仓库/ UserRepository.php名称空间应用程序\存储库;使用应用程序\实体\用户;使用学说\包\DoctrineBundle\存储库\ServiceEntityRepository;使用ob娱乐下载\桥\学说\安全\用户\UserLoaderInterface;类UserRepository扩展ServiceEntityRepository实现了UserLoaderInterface{/ /……公共函数loadUserByUsername(字符串$usernameOrEmail):哦?用户{$entityManager=$这->getEntityManager ();返回$entityManager->createQuery (SELECT u FROM App\Entity\User u WHERE u.username =:query OR u.email =:query)->setParameter (“查询”,$usernameOrEmail)->getOneOrNullResult ();}}
要完成这一步,移除财产
中的用户提供程序中的键security.yaml
:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8
#配置/包/ security.yaml安全:#……提供者:用户:实体:类:应用实体\ \用户
这告诉Symfonyob娱乐下载不自动查询用户。相反,在需要的时候(例如,因为用户模拟,记得我,或其他安全功能被激活),则loadUserByUsername ()
方法UserRepository
将被调用。
内存用户提供商
不建议在实际应用程序中使用此提供程序,因为它有局限性,而且管理用户非常困难。它可能在应用程序原型和不将用户存储在数据库中的有限应用程序中很有用。
这个用户提供程序将所有用户信息存储在一个配置文件中,包括他们的密码。这就是为什么第一步是配置这些用户如何编码他们的密码:
- YAML
- XML
- PHP
1 2 3 4 5 6
#配置/包/ security.yaml安全:#……编码器:Symfony使用这个内部类来表示内存中的用户ob娱乐下载ob娱乐下载Symfony核心组件\ \安全\ \ \用户:“汽车”
然后,运行此命令对用户的明文密码进行编码:
1
$PHP bin/console security: code-password
现在您可以在中配置所有用户信息配置/包/ security.yaml
:
1 2 3 4 5 6 7 8 9
#配置/包/ security.yaml安全:#……提供者:backend_users:记忆:用户:john_admin:{密码:2 y 13美元jxGxc美元……IuqDju”,角色:(“ROLE_ADMIN”)}jane_admin:{密码:2 y 13美元PFi1I美元……rGwXCZ”,角色:[' ROLE_ADMIN ',“ROLE_SUPER_ADMIN”]}
谨慎
当使用内存
提供者,而不是汽车
算法,你必须选择一个编码没有盐(即。bcrypt
).
LDAP用户提供者
这个用户提供程序需要安装特定的依赖关系并使用一些特殊的身份验证提供程序,所以在另一篇文章中解释:针对LDAP服务器进行身份验证.
连锁用户提供商
此用户提供程序组合了两个或多个其他提供程序类型(实体
,内存
而且ldap
)以创建新的用户提供程序。配置提供者的顺序很重要,因为Symfony将从第一个提供者开始查找用户,并将继续在其他提供者中查找,直到找到用户:ob娱乐下载
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#配置/包/ security.yaml安全:#……提供者:backend_users:记忆:#……legacy_users:实体:#……用户:实体:#……all_users:链:提供者:[' legacy_users ',“用户”,“backend_users”]
创建自定义用户提供程序
大多数应用程序不需要创建自定义提供程序。如果您将用户存储在数据库、LDAP服务器或配置文件中,Symfony支持这些功能。ob娱乐下载然而,如果你从一个自定义的位置加载用户(例如通过API或遗留的数据库连接),你需要创建一个自定义的用户提供程序。
首先,确保你遵循了安全指南要创建您的用户
类。
如果你使用:用户
命令创建您的用户
类(并且您回答了表明您需要自定义用户提供程序的问题),该命令将生成一个很好的框架来让您开始:
12 34 56 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
/ / src /安全/ UserProvider.php名称空间应用程序\安全;使用ob娱乐下载\组件\安全\核心\异常\UnsupportedUserException;使用ob娱乐下载\组件\安全\核心\异常\UsernameNotFoundException;使用ob娱乐下载\组件\安全\核心\用户\PasswordUpgraderInterface;使用ob娱乐下载\组件\安全\核心\用户\用户界面;使用ob娱乐下载\组件\安全\核心\用户\UserProviderInterface;类UserProvider实现了UserProviderInterface,PasswordUpgraderInterface{如果您使用sob娱乐下载witch_user *或remember_me等特性,Symfony将调用此方法。* *如果你不使用这些特性,你不需要实现这个方法。* *@return用户界面* *@throws如果用户未找到,则UsernameNotFoundException */公共函数loadUserByUsername(字符串$用户名){//从数据源加载User对象或抛出UsernameNotFoundException异常// $username参数可能不是用户名:// getUsername()返回的值//方法在你的User类。扔新\异常('TODO:在内部填充loadUserByUsername() '.__FILE__);}/** *从会话中重新加载后刷新用户。当用户登录时,在每个请求的开始,从会话中加载* user对象,然后调用此方法。您的工作是确保用户的数据仍然是新鲜的,*例如,重新查询新的用户数据。* *如果你的防火墙是“无状态:true”(对于纯API),这个*方法不会被调用。* *@return用户界面* /公共函数refreshUser(用户界面$用户){如果(!$用户运算符用户){扔新UnsupportedUserException (sprintf (“无效用户类“%s”。”get_class ($用户)));}//确认User对象的数据为“新鲜”后返回一个User对象。//或者抛出UsernameNotFoundException,如果用户不再存在。扔新\异常('TODO: fill in refreshUser() inside '.__FILE__);}/** *告诉Symfoob娱乐下载ny为这个User类使用这个提供程序。* /公共函数supportsClass(字符串$类){返回用户::类= = =$类| | is_subclass_of ($类、用户::类);}/** *升级用户的编码密码,通常用于使用更好的哈希算法。* /公共函数upgradePassword(用户界面$用户、字符串$newEncodedPassword):无效{//待办事项:当使用编码密码时,这个方法应该:/ / 1。将新密码保存在用户存储中/ / 2。用$user->setPassword($newEncodedPassword)更新$user对象;}}
大部分工作已经完成了!阅读代码中的注释并更新TODO部分以完成用户提供程序。完成后,将用户提供程序添加到Symfony中ob娱乐下载security.yaml
:
1 2 3 4 5 6
#配置/包/ security.yaml安全:提供者:#你的用户提供者的名字可以是任何东西your_custom_user_provider:id:App \安全\ UserProvider
最后,更新配置/包/ security.yaml
文件来设置提供者
关键your_custom_user_provider
在所有将使用此自定义用户提供程序的防火墙中。
了解如何从会话刷新用户
在每个请求的末尾(除非您的防火墙无状态的
),你用户
对象被序列化到会话。在下一个请求开始时,它被反序列化,然后传递给您的用户提供者以“刷新”它(例如,针对新用户的Doctrine查询)。
然后,“比较”两个User对象(来自会话的原始User对象和刷新的User对象),以查看它们是否“相等”。默认情况下,为核心AbstractToken
类的返回值进行比较getPassword ()
,getSalt ()
而且getUsername ()
方法。如果其中任何一个不同,您的用户将被注销。这是一种安全措施,可以确保在核心用户数据发生变化时可以取消恶意用户的身份验证。
但是,在某些情况下,这个过程可能会导致意外的身份验证问题。如果你在身份验证上有问题,那可能是你是身份验证成功,但在第一次重定向后立即失去身份验证。
在这种情况下,请检查序列化逻辑(例如。SerializableInterface
),以确保所有必要的字段都是序列化的。
手动比较用户和EquatableInterface
或者,如果你需要对“比较用户”过程进行更多的控制,让你的User类实现EquatableInterface.然后,你isEqualTo ()
方法将在比较用户时调用。
在服务中注入用户提供者
ob娱乐下载Symfony定义了几个与用户提供者相关的服务:
1 2 3 4 5 6 7
$PHP bin/console debug:容器用户。提供者Select one of the following services to display its information: [0] security.user.provider.in_memory [1] security.user.provider.ldap [2] security.user.provider.chain ...
这些服务大多是抽象的,不能被注入到您的服务中。相反,您必须注入Symfony为每个用户提供者创建的正常服务。ob娱乐下载这些服务的名称遵循以下模式:security.user.provider.concrete。< your-provider-name >
.
例如,如果你是构建表单登录并想要注入你的LoginFormAuthenticator
类型的用户提供程序内存
,叫backend_users
,请做以下工作:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/ / src /安全/ LoginFormAuthenticator.php名称空间应用程序\安全;使用ob娱乐下载\组件\安全\核心\用户\InMemoryUserProvider;使用ob娱乐下载\组件\安全\警卫\身份验证\AbstractFormLoginAuthenticator;类LoginFormAuthenticator扩展AbstractFormLoginAuthenticator{私人$userProvider;//在构造函数中修改InMemoryUserProvider类型提示//你正在注入一个不同类型的用户提供程序公共函数__construct(InMemoryUserProvider$userProvider,/ *……* /){$这->userProvider =$userProvider;/ /……}}
然后,注入由Symfony创建的具体服务ob娱乐下载backend_users
用户提供者:
1 2 3 4 5 6
#配置/ services.yaml服务:#……App \安全\ LoginFormAuthenticator:$ userProvider:“@security.user.provider.concrete.backend_users”