Skip to content

Authorization code flow

Use when you want to acquire information about a user.

Flow overview

The flow consists of several steps:

  • Initiating the authorization request.
  • Exchanging the authorization code for an access token.
  • (Optionally)Using the access token to access userinfo endpoint for additional information about the user.

Authorization request

Endpoint URL

The authorization endpoint's URL can be found in the discovery document of Authentication Service. It is returned in authorization_endpoint parameter value. Generally the endpoint URL should not be hard-coded and should be taken from the discovery document. See General information for links to the discovery document for each environment.

Request parameters

  • client_id
    Your unique client identifier issued by Addo Sign.

  • redirect_uri
    The URL to which the Authentication Service will redirect the user-agent to after authentication. It must exactly match one of the URLs registered for your client. Example value: redirect_uri=https://example.com/openid-callback

  • response_type
    Indicates the type of response the client expects from the authorization server. The only available value is code. Example value: response_type=code

  • scope
    A space-delimited list of scopes the client is requesting. Must include the openid scope. Other scopes (like profile, ssn, etc.) may be added to request additional user information. Example value: scope=openid profile ssn

  • nonce
    A unique string value generated by the client to link the authentication request with the ID Token. It is used to mitigate replay attacks by ensuring the token is bound to a specific client session.

  • code_challenge
    Used in the Proof Key for Code Exchange (PKCE) extension to OAuth 2.0, this value is derived from a random code verifier. It strengthens the security of the authorization code flow.

  • code_challenge_method
    Specifies the method used to generate the code challenge from the code verifier. Typically, this is set to S256.

  • state
    An opaque value used by the client to maintain state between the request and the callback. Example value: state=xyz

  • prompt
    Instructs the authorization server whether to prompt the user for re-authentication or consent. Currently, the Authentication Service does not support any values other than login. It should always be set to prompt=login.

  • response_mode
    Specifies how the authorization server returns the authorization response to the client. The response mode determines the method used to deliver parameters such as code, state, error, error_description etc.
    Supported values:

    • query – Parameters are sent as query parameters in the URL. Example: https://example.com/openid-callback?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
    • form_post – Parameters are sent as form-encoded values in an HTTP POST body. Example of the request:
      POST /openid-callback HTTP/1.1
      Host: example.com
      Content-Type: application/x-www-form-urlencoded

      code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
  • ui_locales
    Specifies preferred language of authentication UI. Example value: ui_locales=en. Currently only supported by "MitId" and "Mit ID Erhverv"
    Available values:
    • da for Danish
    • en for English
    • kl for Greenlandic
  • ui_theme
    Specifies preferred theme of the authentication UI. Currently only supported by "MitId" and "Mit ID Erhverv". For details, reach out to your Addo sign representative. Example: ui_theme=some-theme-name

Query parameters approach

One way to initiate the authorization flow is to redirect the user-agent to the Authentication Service with authorization request parameters in the query part of the URL.

Simplified flow diagram

authorize-code-flow.svg

Example requests

Initiate authorization with MitId, do not return ssn in the exchange result, response will be returned as application/x-www-form-urlencoded HTTP POST to redirect_uri.

https://demo.addosign.net/authentication-service/connect/authorize?client_id={your client id}&response_type=code&scope=openid profile&redirect_uri=https://example.com/openid-callback&state=xyz&nonce=TpSPsP-gsDkop_tSdp&acr_values=idp:MitId&prompt=login&response_mode=form_post&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256

ℹ️ Tip
You can use a tool like Postman to read and edit the url above more easily. Paste it into request url field, and Postman should start showing all query parameters in their own separate editable fields.

Same URL with new lines added for clarity:

https://demo.addosign.net/authentication-service/connect/authorize
?client_id={your client id}
&response_type=code
&scope=openid profile
&redirect_uri=https://example.com/openid-callback
&state=xyz
&nonce=TpSPsP-gsDkop_tSdp
&acr_values=idp:MitId
&prompt=login
&response_mode=form_post
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256

Initiate authorization with Tupas, return ssn in the exchange result, response will be returned as HTTP GET with query parameters attached to redirect_uri

https://demo.addosign.net/authentication-service/connect/authorize?client_id={your client id}&response_type=code&scope=openid profile ssn&redirect_uri=https://example.com/openid-callback&state=xyz&nonce=TpSPsP-gsDkop_tSdp&acr_values=idp:Tupas&prompt=login&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256

Same URL with new lines added for clarity:

https://demo.addosign.net/authentication-service/connect/authorize
?client_id={your client id}
&response_type=code
&scope=openid profile ssn
&redirect_uri=https://example.com/openid-callback
&state=xyz
&nonce=TpSPsP-gsDkop_tSdp
&acr_values=idp:Tupas
&prompt=login
&response_mode=query
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256

Pushed authorization request (PAR) approach

One way to initiate the authorization flow is to first send the authorization parameters securely to the Authentication Service through the PAR endpoint. Then redirect the user-agent to Authentication Service with the reference request_uri you get in the response. The endpoint's URL can be found in the discovery document of Authentication Service. It is returned as pushed_authorization_request_endpoint parameter's value. See General information for links to the discovery document for each environment. Besides the normal authorization request parameters, some kind of client authentication information must be present in the request. Currently, the only supported way to authenticate is by sending client_secret together with other request parameters.

Simplified flow diagram

authorize-code-flow-par.svg

Example requests

Initiate authorization with MitId, do not return ssn in the exchange result, response will be returned as application/x-www-form-urlencoded HTTP POST to redirect_uri. New lines added for clarity.

POST /authentication-service/par HTTP/1.1
Host: demo.addosign.net
Content-Type: application/x-www-form-urlencoded

client_id={your client id}
&client_secret={your client secret}
&response_type=code
&scope=openid%20profile
&redirect_uri=https%3A%2F%2Fexample.com%2Fopenid-callback
&state=xyz
&nonce=TpSPsP-gsDkop_tSdp
&acr_values=idp%3AMitId
&prompt=login
&response_mode=form_post
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256

Initiate authorization with Tupas, return ssn in the exchange result, response will be returned as HTTP GET with query parameters attached to redirect_uri. New lines added for clarity.

POST /authentication-service/par HTTP/1.1
Host: demo.addosign.net
Content-Type: application/x-www-form-urlencoded

client_id={your client id}
&client_secret={your client secret}
&response_type=code
&scope=openid%20profile%20ssn
&redirect_uri=https%3A%2F%2Fexample.com%2Fopenid-callback
&state=xyz
&nonce=TpSPsP-gsDkop_tSdp
&acr_values=idp%3ATupas
&prompt=login
&response_mode=query
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256

Success response

HTTP/1.1 200 OK
content-type: application/json; charset=utf-8

{
    "request_uri": "ghEkHlXhhsPVkwj6hXNQizX0CbYhNMI-sXAndZpFWPE",
    "expires_in": 30
}

Error response

HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8

{
    "error": "invalid_client",
    "error_description": "No registered client with this 'client_id' found."
}

Initiating authorization

Initiating authorization is done by redirecting user-agent to the Authentication Service with request_uri you get from the PAR endpoint response.

https://demo.addosign.net/authentication-service/connect/authorize?client_id={your client id}&request_uri=ghEkHlXhhsPVkwj6hXNQizX0CbYhNMI-sXAndZpFWPE

The same URL with new lines added for clarity:

https://demo.addosign.net/authentication-service/connect/authorize
?client_id={your client id}
&request_uri=ghEkHlXhhsPVkwj6hXNQizX0CbYhNMI-sXAndZpFWPE

Authorization response

Response parameters

  • code
    The authorization code issued by the Authentication Service. The client uses this code to request an access token. The authorization code is short-lived and can be used only once.
    Example value: code=SplxlOBeZQQYbYS6WxSbIA

  • state
    An opaque value sent by the client in the authorization request. It is returned unchanged in the response to help maintain state between the request and callback. Example value: state=xyz

  • error
    A code indicating the reason for an authorization failure. Example value: error=access_denied

  • error_description
    A human-readable explanation of the error, providing more details about why the request failed.
    Example value: error_description=User denied the request

Handling authorization response

The request will be made by the user's user-agent(browser). It is up to you to handle the redirection to your system further. Below are examples of requests you will be receiving to your redirect_uri, request method changes depending on the response_mode value set in the authorization request. New lines have been added for clarity.

Success response

query
GET /auth-callback
?code=PYkFy5Tpr-dmOAmFCdTru9M2kSMhYnUWZ96UpLWPe2I
&state=ece4c51e-1dd1-4376-a4f3-dc6ad66c8712 HTTP/1.1
Host: example.com
form_post
POST /openid-callback HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

code=PYkFy5Tpr-dmOAmFCdTru9M2kSMhYnUWZ96UpLWPe2I 
&state=ece4c51e-1dd1-4376-a4f3-dc6ad66c8712

Error response

query
GET /openid-callback
?state=ece4c51e-1dd1-4376-a4f3-dc6ad66c8712
&error=access_denied
&error_description=User%20aborted%20authentication HTTP/1.1
Host: example.com
form_post
POST /openid-callback HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

state=ece4c51e-1dd1-4376-a4f3-dc6ad66c8712
&error=access_denied
&error_description=User%20aborted%20authentication

Exchanging authorization code

Token endpoint URL

The token endpoint's URL can be found in the discovery document of Authentication Service. It is returned in token_endpoint parameter value. Generally, the endpoint URL should not be hard-coded and should be taken from the discovery document. See Environments for links to the discovery document for each environment

Request parameters

  • client_id Your unique client identifier issued by Addo Sign.

  • client_secret
    The secret assigned to your client, issued by Addo Sign.

  • grant_type
    Specifies the type of grant being used. For authorization code flow this is always: grant_type: authorization_code.

  • code
    The authorization code received from the initial authorization request. This code is short-lived and can only be used once.

  • redirect_uri
    The exact redirect_uri value that was used during the authorization request. This must match one of the URIs registered for your client.

  • code_verifier
    The original value used to generate the code_challenge during the authorization request. Required only when using PKCE to secure the exchange.

Request example

POST /authentication-service/connect/token HTTP/1.1
Host: demo.addosign.net
Content-Type: application/x-www-form-urlencoded

client_id={your client id} 
&client_secret= {your client secret}
&code=tBDDizPDtv5NhGht2shToj7bYgbtjsotyMhahXkAVsw
&redirect_uri=https%3A%2F%2Fexample.com%2Fauth%2Fcallback
&grant_type=authorization_code

Response parameters

  • access_token
    The access token issued by the Authentication Service. Use this token to authenticate requests to protected endpoints like "userinfo" endpoint.

  • token_type
    Indicates the type of token returned. For authorization code flow this is always Bearer.

  • expires_in
    The lifetime of the access token in seconds.

  • id_token
    A JSON Web Token (JWT) containing identity claims about the authenticated user.

  • scope
    The scope of the access token.

Response examples

Success response

HTTP/1.1 200 OK
content-type: application/json;charset=UTF-8

{
    "access_token": "eyJhbGciOiJS...1uV",
    "token_type": "Bearer",
    "expires_in": 3599,
    "scope": "openid profile idp",
    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZ...YTIKV"
}

Error response

HTTP/1.1 400 Bad Request
content-type: application/json;charset=UTF-8

{
    "error": "invalid_grant",
    "error_description": "The specified authorization code is no longer valid."
}

Calling userinfo endpoint

ℹ️ Note
Calling userinfo endpoint to get claims about the user is not required, all available claims are already available in the id_token you get from authorization code exchange.

Userinfo endpoint URL

The userinfo endpoint's URL can be found in the discovery document of Authentication Service. It is returned in userinfo_endpoint parameter value. Generally, the endpoint URL should not be hard-coded and should be taken from the discovery document. See Environments for links to the discovery document for each environment

Request example

Here, the authorization JWT used is the same one you get from authorization code exchange, access_token parameter.

GET /authentication-service/connect/userinfo HTTP/1.1
Authorization: Bearer eyJhbGciOiJSU...ScCMGLd090f
Host: demo.addosign.net

Response example

The response contains all claims issued for the identity. The number of claims returned is determined by scopes requested in authorization request.

HTTP/1.1 200 OK
content-type: application/json; charset=utf-8

{
    "idp": "Tupas",
    "sub": "441681f3-4089-4ecd-8c7e-b5dc1c19a470",
    "name": "Some Name",
    "ssn": "000000-000D"
}