OpenID Connect Authorization Code flow for upfront permissions¶
When using the OIDC authorization code flow for authenticating payments, cards or accounts the permission needs to be registered upfront. This requires you to go through some extra steps before you can start with the OIDC authorization code flow.
Steps¶
- Get an access token from BankID OIDC
- Get the BankID with Biometrics OIDC configuration
- Register the permission
- Pass the permission to the redirect flow
- When reaching this point, continue with the steps in the OIDC authorization code flow
- Finally Get the signed permission
1. Get an access token from BankID OIDC¶
Your BankID OIDC client registration needs to have the permissions/client
scope available.
In the scope field you should have openid permissions/client
.
You can get an access token by calling the token endpoint with client credentials. See the BankID OIDC documentation for more information on these access tokens. Here’s an example of a valid request (replace placeholder in Authorization header with your own credentials):
POST /auth/realms/current/protocol/openid-connect/token HTTP/1.1
Host: auth.current.bankid.no
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <Base64-encoded client id:client secret>
grant_type=client_credentials&scope=openid%20permissions%2Fclient
2. Get the BankID with Biometrics OIDC configuration¶
To ensure seamless integration and avoid hardcoding specific endpoints in you application, follow these steps to dynamically fetch the OpenID Connect configuration:
- Determine the appropriate configuration URL based on the environment:
Environment | Url |
---|---|
Production | https://app.bankid.no/.well-known/openid-configuration |
Current (public test environment) | https://current.aletheia-test.idtech.no/.well-known/openid-configuration |
- Send an HTTP GET request to the respective configuration URL using your preferred programming language or API tool.
- Capture the response which will contain a JSON document with the configuration. By dynamically fetching the OIDC configuration, your application remains flexible, allowing for future changes or updates to the endpoints without requiring modifications to your code.
- To enhance the reliability and performance of your integration, we strongly advise implementing response caching for the OIDC configuration.
3. Register the permission¶
This is done by constructing a permission statement containing the payment amount and creditor name, encoding this permission statement using URL safe b64 encoding, and sending a POST request to the permissions endpoint.
First, create the permission statement and encode it as an URL Safe Base 64 string.
const permissionStatement = {
"nonce": "dW5pcXVlIHZhbHVl", // Must be unique
"id": "YmFza2V0IGlk", // Your reference
"payments": [
{
"paymentId": "cGF5bWVudCBpZA", // Your reference
"amount": "123.45",
"currency": "NOK",
"creditorName": "Scrooge McDuck"
}
]
}
// Example implementation of a b64 URL Safe Encoder
function b64URLSafeEncode(stringData) {
return btoa(stringData)
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=/g, "");
}
b64URLSafeEncode(
JSON.stringify(
permissionStatement
)
);
// -> "eyJub25jZSI6ImRXNXBjWFZsSUhaaGJIVmwiLCJpZCI6IlltRnphMlYwSUdsayIsInBheW1lbnRzIjpbeyJwYXltZW50SWQiOiJjR0Y1YldWdWRDQnBaQSIsImFtb3VudCI6IjEyMy40NSIsImN1cnJlbmN5IjoiTk9LIiwiY3JlZGl0b3JOYW1lIjoiU2Nyb29nZSBNY0R1Y2sifV19"
Notes:
- The
nonce
must be a unique value for each permission you register. - Use id (basket ID) and paymentId as references to the payment(s) in your systems. These will not be shown to the end user.
amount
is a decimal amount in string and must use the dot as the decimal separator.
You are now ready to send a POST request to the permissions endpoint, passing the access token received in first step as a bearer token and a permission equaling the URL safe b64 encoding over the permission statement object.
POST /permissions/v1/ HTTP/1.1
Host: api.current.aletheia-test.idtech.no
Content-Type: application/json
Authorization: Bearer <access token from step 1>
{
"type": "payment.v1",
"loa": "sub",
"iat": 1617091752,
"exp": 1617092652,
"permission": < URL safe b64 encoded permission statement from step 2a >
}
Notes:
iat
andexp
are timestamps in seconds since the UNIX epoch.iat
can be at most 1 minute into the past. exp sets the maximum time by which the permission must be granted, and should normally be set just a few minutes into the future.
On a successful request, you will get a response body back containing a permission ID, permission token:
{
"id": "1.BY.MEKrA-00GVtmvWOCDYQko_fSg93LO5n2rBnlj-X4MQg.BiDEl_CgfakqahcXjLrFet_GGpEkR_W8D-RK4hORBO0",
"permissionToken": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjB5Z3hDX3UzQlpPWXlKZ0Y3eDJ0eWtQaTRCTml2cG9KMDBmYjFzTGliUVUiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2MTcwOTU3NDQsImlhdCI6MTYxNzA5MjE0NCwicyI6IjA6LTEjOTIzIiwicCI6IkJpREVsX0NnZmFrcWFoY1hqTHJGZXRfR0dwRWtSX1c4RC1SSzRoT1JCTzAiLCJuYmYiOjE2MTcwOTIxNDh9.39GWvNjNMSKKhKOF4t4HcDnZGNJmLmPT3f612z1VKko"
}
4. Pass permission to redirect flow¶
Pass the permissionToken
as an additional query parameter permission_token
when you start the BankID OIDC flow.
5. Get the signed permission¶
After the user has completed the BankID OIDC flow, you can get the signed permission.
To get the signed permission you can send in a GET request to the permissionId/grant
endpoint. The permissionId
you use is the one that you
got from your permissions POST request. Be aware that it can return a 404 error code
(permission not yet granted) but as mentioned in the api specification you can set up a polling request on the permissionId/grant
endpoint until your initial permission has been signed.
If your permission has been successfully granted you will receive this response:
{
"gv": 1,
"pt": "string",
"type": "string",
"rpId": "bankid-app",
"sv": "2020-10-30@deadbeef",
"iat": 1800000000,
"iss": "string",
"nonce": "string",
"proofKeyId": "string",
"sub": "nnin:010112345",
"permissionId": "string",
"digest": "string"
}
The grant is a JWT token that can be validated as follows:
- In the BankID with Biometrics OIDC configuration (as mentioned here) get the Grant JWK set from the URI pointed to by the
jwks_uri_grants
property in this document. - Check that the token is signed by one of the keys in the Grant JWK set.
- Check that the
nonce
claim inside the token payload is equal to thenonce
in the permission statement created in step