如何在 symfony 中使用多个用户提供者 5. 如何链接它?
Posted
技术标签:
【中文标题】如何在 symfony 中使用多个用户提供者 5. 如何链接它?【英文标题】:How to Use multiple User Providers in symfony 5. How to chain it? 【发布时间】:2021-10-20 23:02:04 【问题描述】:更新的代码和问题:
我使用 symfony Symfony 5.3.6。
我有两种用户:公司和候选人。 我想让他们能够在他们身边进行身份验证。 2个表格来自前端。 (但目前没有表格)。
我使用 lexik_jwt_authentication.jwt_token_authenticator 来验证我的两种用户。 这是我第一次尝试在我的 security.yaml 中为 2 个提供程序编写代码。 当我只有一个时,它起作用了。当我添加公司时,它不再。
这是我在 security.yaml 中更新的代码:
security:
# https://symfony.com/doc/current/security/experimental_authenticators.html
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#c-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
App\Entity\Candidate:
algorithm: auto
App\Entity\Company:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
app_candidate_provider:
entity:
class: App\Entity\Candidate
property: email
app_compagny_provider:
entity:
class: App\Entity\Company
property: email
app_users:
chain:
providers: ['app_candidate_provider', 'app_compagny_provider']
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: false
json_login:
check_path: /api/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: app_users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
# anonymous: lazy
lazy: true
provider: app_user_provider
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - path: ^/admin, roles: ROLE_ADMIN
# - path: ^/profile, roles: ROLE_USER
- path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY
- path: ^/api/candidates, roles: IS_AUTHENTICATED_FULLY
- path: ^/api/company, roles: IS_AUTHENTICATED_FULLY
现在,我的消息错误是:“没有为“login”防火墙上的“json_login”侦听器明确配置提供程序是不明确的,因为有多个注册提供程序..”
我关注了这个帖子: Not configuring explicitly the provider for the "guard" listener on "x" firewall is ambiguous as there is more than one registered provider
通过替换
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: app_users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
与
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: 'app_candidate_provider'
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
还是不行
你知道我哪里出错了吗?
编辑:@mcsky 给出的最终答案是好的:
security:
# https://symfony.com/doc/current/security/experimental_authenticators.html
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#c-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
App\Entity\Candidate:
algorithm: auto
App\Entity\Company:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
app_candidate_provider:
entity:
class: App\Entity\Candidate
property: email
app_compagny_provider:
entity:
class: App\Entity\Company
property: email
app_users:
chain:
providers: ['app_candidate_provider', 'app_compagny_provider']
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
provider: app_users
anonymous: false
json_login:
check_path: /api/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: app_users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
# anonymous: lazy
lazy: true
provider: app_candidate_provider
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - path: ^/admin, roles: ROLE_ADMIN
# - path: ^/profile, roles: ROLE_USER
- path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY
- path: ^/api/candidates, roles: IS_AUTHENTICATED_FULLY
- path: ^/api/company, roles: IS_AUTHENTICATED_FULLY
【问题讨论】:
实现什么?有什么不工作吗?您是否面临yaml 本身的任何问题? 请通过编辑为您的问题添加所有说明。如果您遇到任何错误,请添加消息 您在app_user_provider
之后缺少entity
行,我不确定您是否可以在一个提供程序中指定两个类。但是有chain provider,将两个具体的提供者(candidate
和company
)添加到它,并将其用作防火墙中的提供者。文档有一个很好的例子(我已经链接了当前的,因为password_hashers
暗示你在 5.3 上)。
在链提供者声明中的两个提供者之前有一个providers
键,检查我更新的答案:)
错误信息很清楚,你必须为login
防火墙声明一个用户提供者,因为你已经定义了很多(之前你只有一个,所以Sf接受它)。我为登录防火墙添加了provider: app_users
,检查答案:)
【参考方案1】:
您不能将具有多个类的一个用户提供程序定义为一种配置。它不是为这样工作而设计的。 Symfony 在木头下执行 Symfony\Bridge\Doctrine\Security\User\EntityUserProvider
这个类,你可以看到它只适用于 property
和 email
字符串。
所以我建议你定义两个不同的用户提供者,每个类类型一个。
那么你可以试试这个配置吗?
providers:
app_candidate_provider:
entity:
class: App\Entity\Candidate
property: email
app_compagny_provider:
entity:
class: App\Entity\Company
property: email
app_users:
chain:
providers: ['app_candidate_provider', 'app_compagny_provider']
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
provider: app_users
anonymous: false
json_login:
check_path: /api/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: app_users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
如果有什么不清楚或不起作用,请告诉我
【讨论】:
您忘记了api
节点吗?
Symfony 使用您的firewalls.api
防火墙来验证在您的 API 上发出的每个请求。我从您的帖子中获取了配置,因此您可以使用它。
哦,我忘记了 yaml 路径中的一级,entity
丢失了^^'答案已更新
我更新了我的答案,以使用 msg 在您的问题中建议的链提供商的技巧。它现在应该可以完成工作了
这似乎是 yaml 中的一个错字 :) 你能用你的配置更新你的问题吗?以上是关于如何在 symfony 中使用多个用户提供者 5. 如何链接它?的主要内容,如果未能解决你的问题,请参考以下文章
如何在事件订阅者中访问Symfony 3.3中的登录用户,而不会丢失Web分析器