EU Login API Authentication Bundle

This Symfony bundle provides the necessary to authenticate a request having a specific Authorization HTTP header with a pop token.

Supported tokens are:

  • Opaque PoP access tokens issued by EU Login OpenID Connect (pop [JWS signed AT...])

Requirements

PHP

PHP greater or equal to 7.4.

Symfony

The minimal required version of Symfony is 5.

Extensions

These PHP extensions are required:

  • openssl

  • gmp

  • sodium

Installation

This package has a Symfony Flex recipe that will install configuration files for you.

Default configuration files will be copied in the dev environment.

Step 1

The recommended way to install it is with Composer :

composer require ecphp/eu-login-api-authentication-bundle

This package has a Symfony recipe that will provides the minimum configuration files.

Warning

Be careful, the recipe will enable some routes in your dev environment only. Those routes might be considered as a security issue if they are enabled in the production environment. Those routes are /api/token and /api/user. Find the documentation related to those routes inside the classes themselves. To disable them completely, just delete the file packages/config/routes/dev/eu_login_api_authentication.yaml.

Step 2

Edit the bundle configuration by editing the file config/packages/dev/eu_login_api_authentication.yaml.

eu_login_api_authentication:
    client_id: foo
    client_secret: bar
    environment: acceptance # Available values are: acceptance, production

Step 3

This is the crucial part of your application’s security configuration.

Edit the security settings of your application by edition the file config/packages/security.yaml.

security:
    enable_authenticator_manager: true
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            custom_authenticators:
                - 'eu_login_api_authentication.authenticator'

    access_control:
        - { path: ^/user, role: IS_AUTHENTICATED_FULLY }

Feel free to change these configuration to fits your need. Have a look at the Symfony documentation about security and authentication.

Configuration

Hereunder an example of configuration for this bundle.

eu_login_api_authentication:
    client_id: foo
    client_secret: bar
    environment: acceptance

This bundle uses EU Login to authenticate the incoming requests.

In order to authenticate, you need to be able to create valid tokens through your frontend application.

Sometimes, the frontend application is not ready and you still need to be able to authenticate.

Basically, you need to generate and authenticate tokens without relying on EU Login.

In order to do that, follow the following steps:

  1. Edit the content of your application services.yaml and add:

when@dev:
    services:
        EcPhp\EuLoginApiAuthenticationBundle\Service\LocalEuLoginApiCredentials:
            decorates: 'eu_login_api_authentication.service'
            arguments: ['@.inner']
  1. This will replace the EU Login authentication mechanism by another one which does not require any connection to EU Login.

    Warning

    Be extremely careful to not enable that for production environment.

  2. Read the official Symfony documentation if you want to enable this only for a particular environment.

Usage

Step 1

Follow the Installation procedure.

Step 2

Configure the configuration files accordingly and the security of your Symfony application.

Step 3

Get a valid token from your front-end application.

Step 4

  • Make a request to /api/user with the Authorization header.

curl -X GET "http://127.0.0.1:8000/api/user" -H "Authorization: pop <insert-token-here>"

Step 5

Make sure that the development routes are enabled.

If they are not, create a new file eu-login-api-authentication-bundle.yaml in config/packages/routes/dev/ with the following content:

eu_login_api_authentication_bundle:
    resource: '@EuLoginApiAuthenticationBundle/Resources/config/routes/routes.php'
    prefix: /api

The routes /api/token and /api/user will be available.

Generate a basic token:

GET http://127.0.0.1:8000/api/token

And the response:

HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Type: application/json
Date: Thu, 22 Apr 2021 13:31:44 GMT, Thu, 22 Apr 2021 13:31:44 GMT
Host: 127.0.0.1:8000
X-Debug-Token: 4ff71a
X-Debug-Token-Link: http://127.0.0.1:8000/_profiler/4ff71a
X-Powered-By: PHP/7.4.16
X-Robots-Tag: noindex
Content-Length: 288
Connection: close

{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdCI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUp6ZFdJaU9pSjFjMlZ5WHpZd09ERTNZV013TUdWbFptSWlMQ0poWTNScGRtVWlPblJ5ZFdWOS5DVFRZT1VtcldZaVFPRUUzaUJ0OWhKS1dLRURDQlNUR0twOGxMR3lqNlNJIn0.nEPLVP34eSMge_qz9Jrw88_w6BQHzKKk6aeyj38F8rU"
}

Generate a basic token with custom fields:

POST http://127.0.0.1:8000/api/token
Content-Type: application/json

{ "key" : "value", "list": [1, 2, 3] }

and the response:

HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Type: application/json
Date: Thu, 22 Apr 2021 13:32:38 GMT, Thu, 22 Apr 2021 13:32:38 GMT
Host: 127.0.0.1:8000
X-Debug-Token: 80b1ca
X-Debug-Token-Link: http://127.0.0.1:8000/_profiler/80b1ca
X-Powered-By: PHP/7.4.16
X-Robots-Tag: noindex
Content-Length: 340
Connection: close

{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdCI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUpyWlhraU9pSjJZV3gxWlNJc0lteHBjM1FpT2xzeExESXNNMTBzSW5OMVlpSTZJblZ6WlhKZk5qQTRNVGRoWmpZME5ERXdZeUlzSW1GamRHbDJaU0k2ZEhKMVpYMC5tRmsyZklCVk5vaTJuNV9NZmhYeDVNLTNpNGxGSHMyaEdEbUtCSnV0VzdzIn0.HJY2L-oS09IqVI_q0SGGzarE6l6ZXHQAb14F-1STwzQ"
}

Use /api/user to introspect a token:

GET http://127.0.0.1:8000/api/user
Authorization: pop eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdCI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUp6ZFdJaU9pSjFjMlZ5WHpZd09ERTNPV1ppWVRVeFpUTWlMQ0poWTNScGRtVWlPblJ5ZFdWOS5QcmlsNFhSdUhDV0lXLTUzZThaLWstUzJwSHpDUXNmci1UN094Y2MwbjQ4In0.8MotNjUqlVgzKnAY4CGDm63TdmGrBsPf3_Jvjy_q3qs

And the response:

HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Type: application/json
Date: Thu, 22 Apr 2021 13:29:33 GMT, Thu, 22 Apr 2021 13:29:33 GMT
Host: 127.0.0.1:8000
X-Debug-Token: 716819
X-Debug-Token-Link: http://127.0.0.1:8000/_profiler/716819
X-Powered-By: PHP/7.4.16
X-Robots-Tag: noindex
Content-Length: 42
Connection: close

{
"sub": "user_60817a347e064",
"active": true
}

Introspect a token having custom fields

GET http://127.0.0.1:8000/api/user
Authorization: pop eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdCI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUpyWlhraU9pSjJZV3gxWlNJc0lteHBjM1FpT2xzeExESXNNMTBzSW5OMVlpSTZJblZ6WlhKZk5qQTRNVGRoTldJek1USmlaQ0lzSW1GamRHbDJaU0k2ZEhKMVpYMC4yOVBtYjJSa1NuM0x0MkpWNXNlb0hzWENDRDRPSTl4ZTB2Z2QtMVVmT3JnIn0.10mkjiaaHuO4EdHXAxT6P-Q__f4ztOGgBNPsCIjFdf0

And the response:

HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Type: application/json
Date: Thu, 22 Apr 2021 13:30:52 GMT, Thu, 22 Apr 2021 13:30:52 GMT
Host: 127.0.0.1:8000
X-Debug-Token: 47d353
X-Debug-Token-Link: http://127.0.0.1:8000/_profiler/47d353
X-Powered-By: PHP/7.4.16
X-Robots-Tag: noindex
Content-Length: 71
Connection: close

{
"key": "value",
"list": [
    1,
    2,
    3
],
"sub": "user_60817a5b312bd",
"active": true
}

Tests, code quality and code style

Local development

Follow the procedure described in the Configuration page to setup a local development environment.

Workflow

Every time changes are introduced into the library, Github Actions run the tests written with Behat.

The code style is based on PSR-12 plus a set of custom rules. Find more about the code style in use in the package drupol/php-conventions.

A PHP quality tool, Grumphp, is used to orchestrate all these tasks at each commit on the local machine, but also on the continuous integration tools.

To run the whole tests tasks locally, do

./vendor/bin/grumphp run

Here’s an example of output that shows all the tasks that are setup in Grumphp and that will check your project.

./vendor/bin/grumphp run
GrumPHP is sniffing your code!
Running task  1/13: License... ✔
Running task  2/13: composer_require_checker... ✔
Running task  3/13: composer... ✔
Running task  4/13: ComposerNormalize... ✔
Running task  5/13: YamlLint... ✔
Running task  6/13: JsonLint... ✔
Running task  7/13: PhpLint... ✔
Running task  8/13: TwigCs... ✔
Running task  9/13: PhpCsFixer... ✔
Running task 10/13: Phpcs... ✔
Running task 11/13: PhpStan... ✔
Running task 12/13: Psalm... ✔
Running task 13/13: Behat... 

Contributing

See the file CONTRIBUTING.md but feel free to contribute to this project by sending Github pull requests.

Development

Maintainers

See the MAINTAINERS.txt file.

Documentation

Documentation can be built locally using Sphinx.

To render the documentation locally do the following steps:

Contributors

See the Github insights page.