We use cookies to provide the best site experience.
Ok, don't show again
Close
OpenID Connect API
Integration Guide
Devcode Identity is using OAuth2 and OpenID Connect. It is easy to integrate with Devcode Identity since Devcode Identity is using standards. Client libraries are available for most platforms that will handle the integration with a minimum of configuration.
Table of Contents
1
Describing the OpenID Connect configuration for Devcode Identity
2
Short intro to OpenID Connect
3
Claims are standard data attributes for OpenID Connect
4
The first step in the flow. Redirect the enduser to the authorization endpoint.
5
Send code to token endpoint, using basic auth, to retrieve an id_token with information about the enduser.
6
Retrieve additional onboarding information about the enduser, such as address information or PEP/Sanction screening.
7
Create a sign post.
8
Production, test and mock environments
9
Things to consider if embedding us in an iframe.
10
Complete code examples of integrating Devcode Identity.
11
External documents describing the different standards used.
1
API Overview
The OpenID Connect API is documentet using OpenID Connect Discovery at the standard webfinger URL /.well-known/openid-configuration. The URL for test is (https://demo-api.gii.cloud/.well-known/openid-configuration) and the URL for prod is (https://api.gii.cloud/.well-known/openid-configuration).

The interesting endpoints and properties, documented at the webfinger URL, are:

  • authorization_endpoint: URL called by an end user using a browser. This URL will be accessed with query parameters. See Authentication Request for standard parameters. scope should normally be openid. Extra parameters that are supported are ui_id (the ID of the relying party UI - see documentation for api/rp/ui endpoint) and identity_provider (valid values are e.g. bankid-se and bankid-no) if only one identity provider should be supported.
  • token_endpoint: URL called by relying party to complete a login. See Token Request.
  • revocation_endpoint: URL called by relying party to logout an end user. See OAuth 2.0 Token Revocation.
  • jwks_uri: URL to get valid public keys used by DID to sign JWT. The OpenID Connect client library should automatically call this endpoint to verify tokens.
  • userinfo_endpoint: URL to get user information. See UserInfo Endpoint.
  • scopes_supported: List of scopes that are supported. See Requesting Claims using Scope Values.
  • response_types_supported: List of response types that are supported. code simply tells tells client libraries that DID only supports Authorization Code Flow (not implicit or hybrid).
  • grant_types_supported: Only Authorization Code Flow is supported.
  • display_values_supported: Both full page ( page) and iframe ( popup) is supported. inline-popup is supported for some ID-methods and used when the HTML should be rendered in an iframe with the same origin as the outer frame.
  • claims_parameter_supported: Relying party can send claims-parameters (see Requesting Claims using the "claims" Request Parameter). See below for supported claims.
2
API Control Flow
The control flow always contains four required parts and two optional parts.

  1. Enduser is browsing to website belonging to relying party (merchant).
  2. Relying party is redirecting enduser to authorization_endpoint. See Authorization endpoint.
  3. DID redirects enduser back to the redirect_uri of the relying party together with a code.
  4. Relying party calls the token_endpoint with the code retrieved in step (3) and gets an access_token and id_token. See Token endpoint.
  5. Optional: relying party validates id_token against public keys from jwks_uri.
  6. Optional: relying party calls userinfo_endpoint for possibly additional enduser information (KYC information, PEP, address) using access_token.
3
Claims
The data model used for all endpoints is based on the same claims. Claims can both be send to the authorization endpoint and received by the token and userinfo-endpoints.
Cells marked with O are for onboarding service.

  • ssn: Different national identification numbers or social security numbers. See ssn_type for the type of this value.
  • ssn_type: Possible values are "personnummer" (Swedish national identification number) or "CPR" (Danish national identification number)
  • cloud.gii:identity_provider: The identity provider for the login. Possible values are: bankid-se, bankid-no, nemid, yoti, freja, veriff, sumsub, ftn, idin, itsme, verimi, smart-id, eidas, linkedin, google, facebook, microsoft, twitter and email.
4
Authorization endpoint
GET /api/oauth/auth
The first step in the flow. See Authorization Endpoint for general specification. Redirect the enduser to this URL and provide at least the required query string parameters.

The supported query string parameters are:
All the parameters can also be provided in a JWT-parameter called "request" (see OpenID Connect specification about JWT Requests for details). The relying party must supply DID with their public key before using JWT requests.
Example
Example request to authorization_endpoint
GET /api/oauth/auth
    ?client_id=my-client
    &redirect_uri=https%3A%2F%2Fdemo-app.gii.cloud%2Fcallback
    &response_type=code
    &scope=openid
    &state=6129484611666145821
    &nonce=sdwekjfeiik83kd9dk
    &identity_provider=nemid
    &display=popup
    &ui_id=89
    &claims=%7B%22id_token%22%3A%20%7B%22phone_number%22%3A%20%7B%22essential%22%3A%20true%7D%7D%7D
Host: https://demo-api.gii.cloud

Example response to redirect_uri
GET /callback?
    code=74un8cTaWsEQSaaWgDdeBRh-SofFY0VYRqjQfkoyefo.heq23S0kqXbMIbsfbkPofOoV5hsignywcCLiuGW3Aeg
    &scope=openid
    &state=6129484611666145821
    &display=popup
Host: demo-app.gii.cloud
5
Token Endpoint
POST /api/oauth/token
The second step in the flow. See Token Endpoint for general specification. Take the code from the redirect_uri and call (server to server) the token_endpoint (from the webfinger) using basic auth.
Example

Example request for the code above if the client my-client got the password my-password.
POST /api/oauth/token HTTP/1.1
  Host: https://demo-api.gii.cloud
  Content-Type: application/x-www-form-urlencoded
  Authorization: Basic bXktY2xpZW50Om15LXBhc3N3b3Jk

  grant_type=authorization_code
    &code=74un8cTaWsEQSaaWgDdeBRh-SofFY0VYRqjQfkoyefo.heq23S0kqXbMIbsfbkPofOoV5hsignywcCLiuGW3Aeg
    &redirect_uri=https%3A%2F%2Fdemo-app.gii.cloud%2Fcallback
The token endpoint will on success answer with an access_token and id_token.
HTTP/1.1 200 OK
  Content-Type: application/json
  Cache-Control: no-store
  Pragma: no-cache

  {
   "access_token": "4sjHob0fgOxMpKa1LkJ6D-Y5PMiS4yugAw9rO5oio34.mm40QY1ULclxvN1D_fzjd34bzIUjY16mcY0jSko7i4o",
   "token_type": "Bearer",
   "expires_in": 3600,
   "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJteS1jbGllbnQiLCJiaXJ0aGRhdGUiOiIxOTYzLTA1LTAxIiwiY2xvdWQuZ2lpOmlkZW50aXR5X3Byb3ZpZGVyIjoibmVtaWQiLCJlbWFpbCI6IiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZXhwIjoxNTI0NDk3MzQyLCJmYW1pbHlfbmFtZSI6IiIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoiIiwiaWF0IjoxNTI0NDc1NzQyLCJpc3MiOiJodHRwczovL2RlbW8tYXBpLmdpaS5jbG91ZCIsIm5hbWUiOiJUaW1vdGV1cyBMYXVyc2VuIiwibm9uY2UiOiJzZHdla2pmZWlpazgza2Q5ZGsiLCJwaG9uZV9udW1iZXIiOiIiLCJwaWN0dXJlIjoiIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiIiwicmF0IjoxNTI0NDc1NzQyLCJzc24iOiIwMTA1NjMwMTExIiwic3NuX3R5cGUiOiJDUFIiLCJzdWIiOiJSRXREVUZJd01UQTFOak13TVRFeFhWaG1QMmdvTzJkWGVIcGlJMFpHT24xdFRWMDVNVElwUytPd3hFS1kvQndVbXZ2MHlKbHZ1U1FucmtIa1pKdVRUS1NWbVJ0NFVyaFYifQ.APNkOjCQFyQqb01HtyqJP0zbRbghMEFx4vCQwcmVA5HCjpNlGqFlIUUVygFfiBCmzF0w3nADcT-yuzPK7N1LAp3sE3cpLlbbCONu8mxlCj6KxUPoXeuQjlDJ_ykeV_6nTfZ68HybszxLOqyNhTVTayYMX-E_zzWUQza0OZ67IjgK-sGpr55C7DM84ES-Ms5XfLenjI0kGXZeGC9ZeHUu1Pvsz-exPo-ozefnw0C1E5JOoUcJTp6CSfeOe4eFoVuK5moo55nKj0v7o4NtYmXu1MVq7lB0gGJvwQ-7EH1TnExkPTCeQ6c7xatjfrzyzNkAVU8U-pkfGF1tfMbzsAc2KA"
  }
The id_token is a JWT. The JWT consists of a JOSE Header, followed by a base 64 encoded JWT Claim followed by an encoded JWS, all separated by dots. It is possible to easily inspect a JWT using jwt.io.

Decoding the id_token above by splitting the token on the .s and base64 decoding the first two segments yields the JOSE Header
{
  "alg": "RS256",
  "typ": "JWT"
}
and the JWT Claims
{
  "aud": "my-client",
  "birthdate": "1963-05-01",
  "cloud.gii:identity_provider": "nemid",
  "email": "",
  "email_verified": false,
  "exp": 1524497342,
  "family_name": "",
  "gender": "male",
  "given_name": "",
  "iat": 1524475742,
  "iss": "https://demo-api.gii.cloud",
  "name": "Timoteus Laursen",
  "nonce": "sdwekjfeiik83kd9dk",
  "phone_number": "",
  "picture": "",
  "preferred_username": "",
  "rat": 1524475742,
  "ssn": "0105630111",
  "ssn_type": "CPR",
  "sub": "REtDUFIwMTA1NjMwMTExXVhmP2goO2dXeHpiI0ZGOn1tTV05MTIpS+OwxEKY/BwUmvv0yJlvuSQnrkHkZJuTTKSVmRt4UrhV"
}
6
UserInfo Endpoint
GET /api/oauth/userinfo
For additional onboarding data it is possible to call the userinfo endpoint. See UserInfo Endpoint for general specification.

Cost: The cost of calling this API depends on which data source(s) are used. Usually the cost is per request.

Some data sources (e.g. GDC) are billing for API calls in the test environment too.

Take the access_token from the token endpoint-response and call the userinfo_endpoint (from the webfinger).
Example
HTTP Request
GET /api/oauth/userinfo
Host: demo-api.gii.cloud
Authorization: Bearer 4sjHob0fgOxMpKa1LkJ6D-Y5PMiS4yugAw9rO5oio34.mm40QY1ULclxvN1D_fzjd34bzIUjY16mcY0jSko7i4o
where the string after Bearer is the access_token for the user.

The endpoint will on success answer with a UserInfo-response containing claims (see Claims) for onboarding, such as address information.
HTTP Response
HTTP/1.1 200 OK
  Content-Type: application/json
  Cache-Control: no-store
  Pragma: no-cache

  {
   "address": {
     "country": "SE",
     "formatted": "Sveavägen 49, 113 59 Stockholm",
     "locality": "Stockholm",
     "postal_code": "113 59",
     "street_address": "Sveavägen 49"
   },
   "sub": "REtDUFIwMTA1NjMwMTExXVhmP2goO2dXeHpiI0ZGOn1tTV05MTIpS+OwxEKY/BwUmvv0yJlvuSQnrkHkZJuTTKSVmRt4UrhV"
  }
GET /api/data-sources/userinfo
DID is also exposing a userinfo endpoint for customers that are not logged in through DID.

Cost: The cost of calling this API depends on which data source(s) are used. Usually the cost is per request.

Some data sources (e.g. GDC) are billing for API calls in the test environment too.

Call the endpoint with basic auth (your client_id:cliend_password) and supply ssn_type and ssn and/or name and birthdate (YYYY-MM-DD). Valid values for ssn_type are personnummer (Sweden), CPR (Denmark), and HeTu (Finland). scope can be supplied (see above).
Example
Request
GET /api/data-sources/userinfo?ssn_type=personnummer&ssn=198101011337
Host: demo-api.gii.cloud
Authorization: Basic bXktY2xpZW50Om15LXBhc3N3b3Jk
Response
HTTP/1.1 200 OK
  Content-Type: application/json
  Cache-Control: no-store
  Pragma: no-cache

  {
   "address": {
     "country": "SE",
     "formatted": "Sveavägen 49, 113 59 Stockholm",
     "locality": "Stockholm",
     "postal_code": "113 59",
     "street_address": "Sveavägen 49"
   },
   "sub": "REtDUFIwMTA1NjMwMTExXVhmP2goO2dXeHpiI0ZGOn1tTV05MTIpS+OwxEKY/BwUmvv0yJlvuSQnrkHkZJuTTKSVmRt4UrhV"
  }
7
Sign Endpoint

POST /api/oauth/sign

The sign endpoint must be called before a user should sign something. The request returns the ID of a post to sign that should be sent to the authorization endpoint as sign_id.
Example
HTTP Request
POST /api/oauth/sign
Host: demo-api.gii.cloud
Authorization: Basic bXktY2xpZW50Om15LXBhc3N3b3Jk
Content-Type: application/x-www-form-urlencoded

visible_text=paying&hidden_text=refnr1337&ssn=198101010101&ssn_type=personnummer
where hidden_text, ssn and ssn_type are optional.

The endpoint will answer with JSON.
HTTP Response
HTTP/1.1 201 Created
  Content-Type: application/json
  Cache-Control: no-store
  Pragma: no-cache

  {
   "id": "3939289293033383922"
  }
8
Environments
There is a mock environment, test environment and a production environment.

Mock environment

Host: mock.gii.cloud

OpenID Connect Discovery endpoint: https://mock.gii.cloud/.well-known/openid-configuration

The environment is not integrated with real identity providers but can be used for automated tests and as a way to test the integration without going through the identification steps all the time.

Test environment

Host: demo-api.gii.cloud

OpenID Connect Discovery endpoint: https://demo-api.gii.cloud/.well-known/openid-configuration

This environment is using test certificates and must be accessed with test keys (not production keys). Depending on the identity provider test users must be used.

Production environment

Host: api.gii.cloud

OpenID Connect Discovery endpoint: https://api.gii.cloud/.well-known/openid-configuration

This environment is using production certificated and must e accessed with production keys (not test keys). Real users must be used.


9
Iframe
Permissions

Use the HTML attribute 'allow="camera *" on the iframe if the iframe will contain a provider that will use a webcam (e.g. Yoti).
Universal Links

When integrating with DID using an iframe you need to handle the special case that DID might need to open applications with universal links (e.g. opening BankID). DID will send a message using window.postMessage to inform the parent frame to open the universal link. The parent frame needs this code:
window.addEventListener("message", (e: MessageEvent) => {
    if (e.data) {
        try {
            const data = JSON.parse(e.data);
            if (data.href && data.action === "gii::location_href") {
                // try to open the universal link
                location.href = data.href;
            }
        } catch (err) {
            // nothing
        }
    }
}, false);
Origin

If the page should be rendered with the same origin as the outer frame (to enable password managers) the auth-flow must be started with &display=inline-popup.


did query parameter

Devcode ID might send the user back to the host site, but with the query parameter _did_. The outer frame should then hex-decode the _did_-parameter and append that to the auth-URL.


Callback URL

Read the extra query parameter display with the values popup and page in the callback URL in order to find out if a login completed from within an iframe of the top frame.

Some identity providers do not support being iframed. DID will detect that the login is happening inside an iframe (by reading the displayquery parameter) and from the list view (over all identity providers) open the login method in the top frame (technically target=_top).
10
Examples
Complete .Net Core example implementation with source code on Github.
11
References
The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. This specification replaces and obsoletes the OAuth 1.0 protocol described in RFC 5849.
This document proposes an additional endpoint for OAuth authorization servers, which allows clients to notify the authorization server that a previously obtained refresh or access token is no longer needed. This allows the authorization server to clean up security credentials. A revocation request will invalidate the actual token and, if applicable, other tokens based on the same authorization grant.
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.

This specification defines the core OpenID Connect functionality: authentication built on top of OAuth 2.0 and the use of Claims to communicate information about the End-User. It also describes the security and privacy considerations for using OpenID Connect.
This specification defines a mechanism for an OpenID Connect Relying Party to discover the End-User's OpenID Provider and obtain information needed to interact with it, including its OAuth 2.0 endpoint locations.
This document gives additional security considerations for OAuth, beyond those in the OAuth 2.0 specification, based on a comprehensive threat model for the OAuth 2.0 protocol.