isGranted возвращает false для вошедшего в систему пользователя JWT — Symfony API-Platform AWS-EB

Я развернул приложение API-платформы с токеном JWT в ElasticBeanstalk, которое, как обычно, отлично работает на моем локальном сервере.

Однако на 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());

Я провел беглое сравнение phpinfo() между моей локальной установкой и установкой на AWS-EB и не смог найти явного несоответствия.

Это конфигурация для JWT по адресу /config/packages/lexik_jwt_authentication.yaml.

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

person BernardA    schedule 14.03.2020    source источник
comment
Каков маршрут и конфигурация брандмауэра? Работают ли другие защищенные пути, для которых требуется токен JWT?   -  person yivi    schedule 14.03.2020
comment
Я добавил security.yaml в тело вопроса. Что касается маршрутов, то это graphql, все они выглядят так: https:mywebsite/api/graphql   -  person BernardA    schedule 14.03.2020
comment
Согласно вашим правилам контроля доступа, /api/graphql не требует аутентификации.   -  person yivi    schedule 14.03.2020
comment
Работают ли другие маршруты на /api/graphql и требуют аутентификации? Я бы переместил правило IS_AUTHENTICATED в ваш раздел управления доступом, а в аннотации безопасности оставил бы только object == user.   -  person yivi    schedule 14.03.2020
comment
Правильно: /api/graphql не требует аутентификации. Есть несколько вопросов, которые открыты для всех. Но чтобы получить большую часть информации о пользователе, контроль доступа осуществляется на уровне запроса, и, как и в случае с рассматриваемым запросом, как пользователь должен быть аутентифицирован, так и сам должен быть пользователем для доступа к информации. . В целом я не думаю, что это как-то связано с конфигурацией безопасности. Как было сказано, все отлично работает локально с той же конфигурацией.   -  person BernardA    schedule 14.03.2020
comment
не хотите объяснить, почему этот вопрос был отклонен? Что с этим не так? Или у тебя просто был плохой день?   -  person BernardA    schedule 14.03.2020
comment
Я никак не голосовал по этому вопросу.   -  person yivi    schedule 14.03.2020


Ответы (1)


После дальнейших исследований я обнаружил, что Apache удаляет токен авторизации из запроса.

В методе supports из /lexik/jwt-authenticator-bundle/Security/Guard/JWTTokenAuthenticator дамп, как показано ниже, не будет включать токен на AWS:

 var_dump($request->headers->all());
 var_dump($_SERVER);

Согласно этому вопросу, это проблема конфигурации Apache, которая не принимает авторизацию заголовки.

Указанное решение состоит в том, чтобы добавить следующее к .htaccess:

 SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

Это решает проблему, хотя следует отметить, что локальная установка Apache работает нормально без вышеуказанного редактирования .htaccess.

Таким образом, также должна быть возможность напрямую изменить конфигурацию Apache, но я не смог найти, как это сделать.

РЕДАКТИРОВАТЬ: Позже я нашел конкретную инструкцию в документах «JWT-Token» следующим образом, которая подтверждает это решение на по этой ссылке.

person BernardA    schedule 22.03.2020