Skip to main content

2. Integration Steps

Prerequisites


Step 1 – User credential issuance

The organization’s LEAR uses the Issuer service to issue a Verifiable Credential to the employee or user who will log in through the public client.

  • The credential is bound to the user’s DID.

  • It includes roles or permissions within the organization.

  • The credential is stored in the user’s Wallet application, which can later present it during authentication.

Outcome:
User holds a valid LEAR Credential stored in their wallet and ready to be presented during the login process.

Step 2 – Client configuration

Client type: Public (web or mobile app).

  • Register the client in the Verifier’s Authorization Server with its redirect_uri.

  • Obtain and store the assigned client_id.

  • Implement PKCE support (code_challenge / code_verifier) to protect the authorization code exchange.

  • Ensure secure handling of redirects and state parameters.

Outcome:
Public client is configured and ready to initiate the OAuth 2.1 Authorization Code Flow with PKCE.

Step 3 – Authorization request

The public client initiates the authentication process by redirecting the user to the Verifier’s Authorization Endpoint, including the required parameters:

  • client_id

  • redirect_uri

  • response_type=code

  • scope (e.g. openid eidas)

  • statenonce

  • code_challenge (derived from code_verifier)

  • code_challenge_method=S256

Non-normative example:

GET /oidc/auth?
client_id=https%3A%2F%2Fapp.client.com
&redirect_uri=https%3A%2F%2Fapp.client.org%2F
&response_type=code
&scope=openid%20eidas
&nonce=1234567890abcdef1234567890abcdefXYZabc
&state=abcdef1234567890abcdef1234567890XYZ987
&code_challenge=AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abcdEfGhI
&code_challenge_method=S256
Host: authserver.example.org

Outcome:
User is redirected to the Verifier login screen and authenticates using their Wallet and Verifiable Credential.

Step 4 – Authorization response

After successful authentication and consent, the Authorization Server redirects the user back to the client with the authorization code and state.

Non-normative example:

HTTP/1.1 302 Found
Location: https://app.client.org/?
code=A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v2W3x4Y5z6
&state=1234abcd5678efgh9012ijkl3456mnop7890qrst

Outcome:
The public client receives the authorization code and verifies that the returned state matches the one it initially sent.

Step 5 – Token request

The client exchanges the received authorization code for tokens by calling the Token Endpoint.
This request must include the original code_verifier used to generate the challenge.

Non-normative example:

POST /oauth2/token HTTP/1.1
Host: authserver.example.org
Content-Type: application/json
Content-Length: 311

{
  "grant_type": "authorization_code",
  "client_id": "https://app.client.com",
  "code_verifier": "b7f9a4b52e6347a1b8f2c3d1a6...9e0f1ABCxyz",
  "code": "AbC123xYz0987QrStUvWxYz6543LmNoPqRsTuVwXyZ=",
  "redirect_uri": "https://app.client.org/"
}

Outcome:
The Verifier validates the code and code_verifier and issues an access token and ID token.

Step 6 – Token response

Non-normative example:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "access_token": "eyJhbGciOiJFQ0RILUVTIiwiZ...qtAlx1oFIUpQQ",
  "expires_in": 3600,
  "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...p-QV30",
  "scope": "openid profile email",
  "token_type": "Bearer"
}

Outcome:

  • access_token is used to call protected APIs on the Verifier.

  • id_token identifies the authenticated user.

  • Tokens have a limited lifetime (typically 1 hour).

Step 7 – Use access token

The public client includes the access token in the Authorization header when calling Verifier-protected APIs:

Authorization: Bearer eyJhbGciOiJFQ0RILUVTIiwiZ...

The Verifier validates the token, checks its signature and expiration, and grants access to the requested resources.

Pitfalls to avoid

  • Mismatch between redirect_uri in request and registration.

  • Missing or incorrect code_verifier / code_challenge.

  • Using a weak or predictable state value (CSRF risk).

  • Reusing authorization codes.

  • Not handling token expiration and refresh flow.

  • Forgetting to set Cache-Control: no-store in responses.