isGranted 为登录的用户 JWT 返回 false - Symfony API-Platform AWS-EB
Posted
技术标签:
【中文标题】isGranted 为登录的用户 JWT 返回 false - Symfony API-Platform AWS-EB【英文标题】:isGranted returns false for logged in user JWT - Symfony API-Platform AWS-EB 【发布时间】:2020-06-26 04:10:33 【问题描述】:我已经使用 JWT 令牌向 ElasticBeanstalk 部署了一个 API-Platform 应用程序,它像往常一样在我的本地服务器上运行良好。
在 EB 上,尽管提供了正确的 BearerToken
,但它拒绝访问已登录的用户。
这是抛出的错误:
"errors": [
"message": "Access Denied.",
"extensions":
"category": "graphql"
,
"locations": [
"line": 6,
"column": 9
],
"path": [
"retrievedQueryUser"
]
],
"data":
"retrievedQueryUser": null
有问题的查询尝试通过以下graphql
配置检索用户配置文件信息:
* "retrievedQuery"=
* "item_query"=UserProfileResolver::class,
* "normalization_context"="groups"="get-owner",
* "security"="is_granted('IS_AUTHENTICATED_FULLY') and object == user"
* ,
因此,检查用户是否为IS_AUTHENTICATED_FULLY
以及是否是他/她自己尝试执行查询应该是一件简单的事情。
据我所知,通过下面的 /vendor/symfony/security-core/Authorization/AuthorizationChecker.php
转储,它未能检索到令牌。
var_dump($this->tokenStorage->getToken()->getUser()->getUsername());
我粗略地比较了我的本地安装和 AWS-EB 上的 phpinfo()
,但没有发现任何明显的不匹配。
这是/config/packages/lexik_jwt_authentication.yaml
的 JWT 配置。
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
user_identity_field: email
token_ttl: 1800
只是为了确认用户能够登录。它通过了失败的isGranted()
检查。
有什么想法吗?
编辑 - 添加`/config/packages/security.yaml
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
App\Entity\User:
algorithm: auto
#algorithm: bcrypt
#algorithm: argon2i
cost: 12
providers:
database:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
refresh:
pattern: ^/api/token/refresh
stateless: true
anonymous: true
api:
pattern: ^/api
stateless: true
anonymous: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
guard:
authenticators:
- app.google_login_authenticator
- App\Security\TokenAuthenticator
entry_point: App\Security\TokenAuthenticator
user_checker: App\Security\UserEnabledChecker
access_control:
- path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY
- path: ^/admin, roles: ROLE_SUPERADMIN
- path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY
- path: ^/api, roles: IS_AUTHENTICATED_ANONYMOUSLY
role_hierarchy:
ROLE_PROVIDER: ROLE_USER
ROLE_ADMIN: [ROLE_PROVIDER, ROLE_EDITOR]
ROLE_SUPERADMIN: ROLE_ADMIN
【问题讨论】:
路由和防火墙配置是什么?其他需要 JWT 令牌的受保护路径是否有效? 我在问题正文中添加了security.yaml
。关于路线,这是graphql
,它们都看起来像:https:mywebsite/api/graphql
根据您的访问控制规则,/api/graphql
不需要身份验证。
/api/graphql
上的其他路由是否需要身份验证工作?我会将IS_AUTHENTICATED
规则移到您的访问控制部分,并在安全注释上添加object == user
。
没错:/api/graphql
不需要身份验证。有几个查询对任何人开放。但是为了获取大部分用户信息,访问控制在查询级别就位,并且,在有问题的查询的情况下,用户都应该经过身份验证,并且应该是他/她自己来访问信息的用户.总的来说,我认为这与安全配置无关。如前所述,使用相同的配置在本地一切正常。
【参考方案1】:
经过进一步研究,我发现 Apache 正在从请求中剥离授权令牌。
在/lexik/jwt-authenticator-bundle/Security/Guard/JWTTokenAuthenticator
的方法supports
上,如下转储将不包含AWS 上的令牌:
var_dump($request->headers->all());
var_dump($_SERVER);
根据this question,这是不接受授权标头的 Apache 配置问题。
指示的解决方案是将以下内容添加到.htaccess
:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
这解决了这个问题,但应该注意,如果没有对 .htaccess
进行上述编辑,本地 Apache 安装工作正常。
所以,也应该可以直接更改 Apache 配置,但我找不到如何去做。
编辑:后来我在“JWT-Token”文档上找到了如下的特定说明,确认了this link 上的解决方案。
【讨论】:
以上是关于isGranted 为登录的用户 JWT 返回 false - Symfony API-Platform AWS-EB的主要内容,如果未能解决你的问题,请参考以下文章