具有多个防火墙和多个共享保护身份验证器的 Symfony 3.4 防火墙配置
Symfony 3.4 firewall configuration with multiple firewalls and multiple shared guard authenticators
这是一个 Symfony 3.4 应用程序,具有网站前端和访问相同后端的移动应用程序。用户可以通过
登录
- 提交用户名和密码(表单登录)
- 使用 google 帐户进行身份验证
- 使用 Facebook 帐户进行身份验证
以前只有一种登录方式(用户名+密码)。身份验证和防火墙配置有效。添加社交网络身份验证需要更改防火墙配置,现在防护身份验证已部分损坏。
到目前为止我有信心的是我们需要为网络用户(主要)和移动应用程序用户(api)设置单独的防火墙。 Web 用户经过一次身份验证,然后登录的用户信息存储在会话 cookie 中,但移动应用程序用户在每次传入请求时都经过身份验证。当移动用户成功登录时,他们会收到一个 jwt 令牌作为响应,他们将在每个后续请求中发送该令牌。
最大的问题似乎是防火墙配置的其余部分。在当前配置中,"main" 防火墙按预期工作。但是针对移动用户的 "api" 防火墙有些问题。登录使用相同的保护身份验证器,以便它们 return jwt 令牌如预期的那样。但是随令牌发送的后续请求都会导致 403 访问被拒绝响应。我怀疑词法验证器永远不会从请求中获取 jwt 令牌,所以看起来用户从未登录过。
验证器已经过测试,它们似乎对网络用户和移动用户都能正常工作。 lexik jwt authenticator 的配置也是正确的 - 或者自从移动用户仍然拥有单个验证器以来它没有改变。这意味着密钥、密码短语、令牌 ttl。
一个可行的想法是为移动登录 url 和其余移动路由设置单独的防火墙,因为它们由不同的身份验证器处理。我试过了,情况没有任何改善:登录有效,但 jwt 身份验证无效。以下security.yml的相关部分:
security:
...
providers:
db_users:
entity: { ... }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js|api)/(password/reset)
security: false
api:
pattern: ^/api/
stateless: true
lexik_jwt: ~
anonymous: false
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
- lexik_jwt_authentication.jwt_token_authenticator
entry_point: main.form_login_authenticator
main:
pattern: ^/
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
entry_point: main.form_login_authenticator
form_login:
remember_me: true
login_path: login
check_path: login
always_use_default_target_path: true
default_target_path: /redirect
target_path_parameter: _target_path
use_referer: false
require_previous_session: false
anonymous: true
...
这里有什么问题?我应该如何调试这个问题? (除了使用邮递员模拟来自移动应用程序的 json 请求)
附加信息:所有三个自定义身份验证器都会创建一个 jwt 令牌,例如:
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
// mobile users:
if ( $request->getRequestFormat() == 'json') {
return new JsonResponse(['token' => $this->jwtManager->create($token->getUser())]);
// web users handled here
}
然后关于访问模式(或请求如何处理以及由哪个身份验证器处理),这是来自 main.form_login_authenticator
的示例
public function supports(Request $request)
{
return ('login' === $request->attributes->get('_route') || 'api_login_check' === $request->attributes->get('_route'))
&& $request->isMethod('POST');
}
不过,验证器似乎按预期工作。登录工作。不起作用的是使用 jwt 令牌保持登录状态。
首先,对于 api 防火墙,你应该只有 jwt 验证器,因为即使 auth.使用社交网络完成后,您必须生成自己的 jwt 令牌。
其次,你能把你的访问模式发给我们吗?这可以给我们更多的线索。
第三,我不确定 api 防火墙的入口点是否应该与第一个 (https://symfony.com/doc/current/components/security/firewall.html#entrypoint)
终于成功了。该解决方案的主要思想是分离防火墙:一个用于移动登录路由,另一个用于其余移动 (api) 路由。这是有效的配置,遗漏用三个点标记。 main
防火墙配置如问题所示。
security:
...
firewalls:
...
api_login:
pattern: ^/api/(login|google-login|fb-login)
stateless: true
anonymous: true
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
entry_point: main.form_login_authenticator
api:
pattern: ^/api
stateless: true
guard:
provider: db_users
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
...
身份验证器服务名称的前缀最初来自防火墙的名称main
,这不再有意义,因为它们现在在多个防火墙之间共享。
这是一个 Symfony 3.4 应用程序,具有网站前端和访问相同后端的移动应用程序。用户可以通过
登录- 提交用户名和密码(表单登录)
- 使用 google 帐户进行身份验证
- 使用 Facebook 帐户进行身份验证
以前只有一种登录方式(用户名+密码)。身份验证和防火墙配置有效。添加社交网络身份验证需要更改防火墙配置,现在防护身份验证已部分损坏。
到目前为止我有信心的是我们需要为网络用户(主要)和移动应用程序用户(api)设置单独的防火墙。 Web 用户经过一次身份验证,然后登录的用户信息存储在会话 cookie 中,但移动应用程序用户在每次传入请求时都经过身份验证。当移动用户成功登录时,他们会收到一个 jwt 令牌作为响应,他们将在每个后续请求中发送该令牌。
最大的问题似乎是防火墙配置的其余部分。在当前配置中,"main" 防火墙按预期工作。但是针对移动用户的 "api" 防火墙有些问题。登录使用相同的保护身份验证器,以便它们 return jwt 令牌如预期的那样。但是随令牌发送的后续请求都会导致 403 访问被拒绝响应。我怀疑词法验证器永远不会从请求中获取 jwt 令牌,所以看起来用户从未登录过。
验证器已经过测试,它们似乎对网络用户和移动用户都能正常工作。 lexik jwt authenticator 的配置也是正确的 - 或者自从移动用户仍然拥有单个验证器以来它没有改变。这意味着密钥、密码短语、令牌 ttl。
一个可行的想法是为移动登录 url 和其余移动路由设置单独的防火墙,因为它们由不同的身份验证器处理。我试过了,情况没有任何改善:登录有效,但 jwt 身份验证无效。以下security.yml的相关部分:
security:
...
providers:
db_users:
entity: { ... }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js|api)/(password/reset)
security: false
api:
pattern: ^/api/
stateless: true
lexik_jwt: ~
anonymous: false
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
- lexik_jwt_authentication.jwt_token_authenticator
entry_point: main.form_login_authenticator
main:
pattern: ^/
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
entry_point: main.form_login_authenticator
form_login:
remember_me: true
login_path: login
check_path: login
always_use_default_target_path: true
default_target_path: /redirect
target_path_parameter: _target_path
use_referer: false
require_previous_session: false
anonymous: true
...
这里有什么问题?我应该如何调试这个问题? (除了使用邮递员模拟来自移动应用程序的 json 请求)
附加信息:所有三个自定义身份验证器都会创建一个 jwt 令牌,例如:
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
// mobile users:
if ( $request->getRequestFormat() == 'json') {
return new JsonResponse(['token' => $this->jwtManager->create($token->getUser())]);
// web users handled here
}
然后关于访问模式(或请求如何处理以及由哪个身份验证器处理),这是来自 main.form_login_authenticator
public function supports(Request $request)
{
return ('login' === $request->attributes->get('_route') || 'api_login_check' === $request->attributes->get('_route'))
&& $request->isMethod('POST');
}
不过,验证器似乎按预期工作。登录工作。不起作用的是使用 jwt 令牌保持登录状态。
首先,对于 api 防火墙,你应该只有 jwt 验证器,因为即使 auth.使用社交网络完成后,您必须生成自己的 jwt 令牌。
其次,你能把你的访问模式发给我们吗?这可以给我们更多的线索。
第三,我不确定 api 防火墙的入口点是否应该与第一个 (https://symfony.com/doc/current/components/security/firewall.html#entrypoint)
终于成功了。该解决方案的主要思想是分离防火墙:一个用于移动登录路由,另一个用于其余移动 (api) 路由。这是有效的配置,遗漏用三个点标记。 main
防火墙配置如问题所示。
security:
...
firewalls:
...
api_login:
pattern: ^/api/(login|google-login|fb-login)
stateless: true
anonymous: true
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
entry_point: main.form_login_authenticator
api:
pattern: ^/api
stateless: true
guard:
provider: db_users
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
...
身份验证器服务名称的前缀最初来自防火墙的名称main
,这不再有意义,因为它们现在在多个防火墙之间共享。