8

I'd like to add the "Authorize" button on Swagger, like described here : https://api-platform.com/docs/core/jwt#documenting-the-authentication-mechanism-with-swaggeropen-api

I installed LexikJWTAuthenticationBundle, it works fine with Curl. But when I browse to http://localhost:8000/api, I only see {"code":401,"message":"JWT Token not found"}.

Am I missing something?

Here's my security.yaml:

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
    providers:
        db_provider:
            entity:
                class: App\Entity\User
                property: username
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        api_login:
            pattern: ^/api/login
            stateless: true
            anonymous: true
            form_login:
                check_path: /api/login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
                require_previous_session: false
        api:
            pattern: ^/api
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
        main:
            pattern: ^/
            anonymous: ~
            provider: db_provider
            form_login:
                login_path: app_security_login
                check_path: app_security_login
                csrf_token_generator: security.csrf.token_manager
            logout:
                path: /logout
                target: /
            remember_me:
                secret: '%kernel.secret%'
                lifetime: 604800
                path: /

    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: ROLE_USER }

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    access_decision_manager:
        strategy: unanimous

And my api_platform.yaml:

api_platform:
    title: 'My project'
    version: '0.0.1'
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']
    swagger:
         api_keys:
             apiKey:
                name: Authorization
                type: header
yivi
  • 42,438
  • 18
  • 116
  • 138
user9384432
  • 81
  • 1
  • 3

3 Answers3

10

Bit late to this, but I faced this same issue. Your security configuration is stating that any route beginning with /api requires authentication, which includes /api itself. If you want to keep the documentation on the /api route, add a trailing slash to the security configuration;

firewalls:
    ...
    api:
        pattern: ^/api/

and

access_control:
    - { path: ^/api/, roles: IS_AUTHENTICATED_FULLY }

This will leave /api as publicly accessible, whilst requiring a valid token to be provided for /api/*.

Alternatively, you can leave the security configuration as it is and move the documentation to a different URL (e.g. /docs). For this, you may need to add /docs as an IS_AUTHENTICATED_ANONYMOUSLY path under access_control depending on your other rules.

Then when the documentation page is accessible, click the Authorize button at the top of the page and enter Bearer <valid JWT token>.

Chris Brown
  • 4,445
  • 3
  • 28
  • 36
1

It's old but here is the solution in 2021

You have to decorate open api factory

Edit :

Don't put hyphen (-) in the name of the authorization and in the scheme key otherwise it won't work (probably other special characters)

In config/packages/api_platform.yaml :

swagger:
    versions: [3]
    api_keys:
        JWT: // The name of the authorization to display on swagger UI
            name: Authorization
            type: header

In config/services.yaml :

App\OpenApi\JwtDecorator:
decorates: 'api_platform.openapi.factory'
arguments: [ '@App\OpenApi\JwtDecorator.inner' ]
autoconfigure: false
enter code here

The decorating service : in OpenApi\JwtDecorator

class JwtDecorator implements OpenApiFactoryInterface
{
    public function __construct(
        private OpenApiFactoryInterface $decorated
    ) {}

    public function __invoke(array $context = []): \ApiPlatform\Core\OpenApi\OpenApi
    {
        $openApi = ($this->decorated)($context);

        $schemas = $openApi->getComponents()->getSecuritySchemes();
        $schemas['JWT'] = new \ArrayObject([
            'type' => 'http',
            'scheme' => 'bearer',
            'bearerFormat' => 'JWT'
        ]);

        return $openApi;
    }
}
DrK
  • 144
  • 1
  • 10
0

I could fix my problem. In my case problem was, in public and private openssl keys. First I fixed it, the second, problem was in encoding. I used the source below to achieve result. Just take a look to link below LexikJWTAuthenticationBundleSandbox