New Feature Preview: JWT authentication for REST API and GraphQL in v3.2

Well-developed headless capabilities are a strong feature of Ibexa’s DXP. REST API and GraphQL, available out of the box, are powerful, fast, and reliable providing access to all of the product’s core capabilities. These APIs are widely used by developers to build elegant front-end JavaScript Single Page Applications, for connecting standalone mobile applications as well as serve many other cases.

The technology market is changing rapidly, especially when it comes to authentication, authorization, or generally speaking, communication between different services. 

Due to its nature, authentication is always a little tricky. The wide range of available solutions does not make it easier, as it would not be possible to follow, implement, and deliver all of them in Ibexa’s DXP.  

So, we are proud to take a step forward and introduce a new method of authentication against our public headless APIs. Up until now it was only possible to access them using either via session-based authentication or HTTP basic auth. With v3.2 (due out shortly) we introduce a new, modern authentication method – JSON Web Token (JWT). JWT is a safe, fast, and acceptably simple technology that has been around for a while and is broadly used in the modern web development world.

JSON Web Token - JWT

JWT is a mechanism used in the context of web APIs but also more broadly in the general terms of web and mobile applications. Instead of using a traditional session cookie or HTTP based auth headers, in this method, a unique token is generated and must be used for every single request that requires a permission check. Such a token has its TTL (Time To Live) after which is no longer usable and a new token must be generated again.  

Credentials need to be sent to the application only once when requesting a new token. Once generated, the token by itself is enough to successfully authenticate in the system. 

For more information please refer to JWT.io

Configuration in Ibexa DXP

In v3.2 of Ibexa’s DXP, JWT authentication is an opt-in feature, hence it must be enabled to be available.  

As it was previously used exclusively for authentication in Page Builder, it is already installed, and some configuration should already be available in the system. Some basic configuration can be found in config/packages/lexik_jwt_authentication.yaml file. As opposed to what Page Builder needs, full JWT support requires authorization_header option to be enabled.  

The whole configuration might look like the following:

lexik_jwt_authentication:
    secret_key: '%env(APP_SECRET)%'
    encoder:
        signature_algorithm: HS256
    # Disabled by default, because Page builder uses a custom extractor
    token_extractors:
        authorization_header:
            enabled: true
        cookie:
            enabled: false
        query_parameter:
            enabled: false

Moreover, a new Symfony Firewall is also required. It should be defined before ezpublish_front in config/packages/security.yaml file.

For REST API the following firewall should be configured:

ezplatform_rest:
    request_matcher: EzSystems\EzPlatformAdminUi\REST\Security\NonAdminRESTRequestMatcher
    user_checker: eZ\Publish\Core\MVC\Symfony\Security\UserChecker
    anonymous: ~
    guard:
        authenticators:
            - lexik_jwt_authentication.jwt_token_authenticator
        entry_point: lexik_jwt_authentication.jwt_token_authenticator
    stateless: true

For GraphQL it’s almost the same:

ezplatform_graphql:
    request_matcher: EzSystems\EzPlatformGraphQL\Security\NonAdminGraphQLRequestMatcher
    user_checker: eZ\Publish\Core\MVC\Symfony\Security\UserChecker
    anonymous: ~
    guard:
        authenticators:
            - lexik_jwt_authentication.jwt_token_authenticator
        entry_point: lexik_jwt_authentication.jwt_token_authenticator
    stateless: true

In the newest release these firewalls are already included and commented-out in the default configuration file.

Usage

This new feature adds a new REST API endpoint and GraphQL mutation that can be called to obtain a token.

MethodPOST
Endpoint/api/ezp/v2/user/token/jwt

Accept header
Content-Type header

application/vnd.ez.api.JWT+json
application/vnd.ez.api.JWTInput+json

Example of a request body:

{
    "JWTInput": {
        "username": "admin",
        "password": "publish"
    }
}

And the expected response if given credentials are valid:

{
    "JWT": { 
        "_media-type": "application/vnd.ez.api.JWTToken+json",
        "_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDAxNjEyMzgsImV4cCI6MTYwMDE2NDgzOCwicm9sZXMiOlsiUk9MRV9VU0VSIl0sInVzZXJuYW1lIjoiYWRtaW4ifQ.AXfviM-usgDWSpYuRbNp294d2s2nNi720xhPyu6V3Ro"
    }
}

Now, the token needs to be set as a value for the Bearer-Token Authentication method in the client application. 

Summary

This new convenient authentication method helps Ibexa’s DXP deliver an even better developer experience by making work with headless quicker, smoother, and frictionless. Stay tuned for more developer experience improvements in the forthcoming version! 

Discover which skills and technology are required to successfully implement Headless CMS in the Enterprise

Headless CMS in the Enterprise

This eBook covers the considerations you should take into account to have the right skills and technology in place as well as what to pay attention to when it comes to the cost of ownership to ensure successful digital transformation in your organization.

Download eBook now
Headless CMS in the Enterprise

Insights and News