# CIBA (OIDC extension)
Page contents
# About CIBA
OpenID Connect CIBA (Client Initiated Backchannel Authentication (opens new window)) is an extension of the OpenID Connect protocol that allows the client application to initiate the authentication process and receive real-time updates on the authentication status.
# Differences between CIBA and the authorization code flow
The authorization code flow and the CIBA flow are two different authentication flows in the OpenID Connect protocol.
In the authorization code flow, the client application redirects the user to the authorisation server, where the user logs in and provides consent. After successful authentication, the authorisation server redirects the user back to the client application with an authorization code. The client application then exchanges this code for an access token and a refresh token by making a direct request to the authorization server's token endpoint. This flow is primarily designed for web applications and requires user interaction during the entire authentication process.
On the other hand, the CIBA flow introduces a more flexible and asynchronous approach to authentication. In this flow, the client application initiates the authentication process by making a backchannel authentication request to the authorization server. The server responds with a unique authentication reference. The client can then receive real-time updates on the authentication status by polling the token endpoint. This flow is particularly useful in scenarios where the client application may not have a user interface or needs to authenticate the user on a different device, or when it is desirable to create a completely customised login flow with complete control over the UI in a web application or a mobile app (similar to the Authentication REST API headless flow).
# Application flow
A successful CIBA flow will follow the following pattern:
- The client makes a call to the
backchannel_authentication_endpoint
, indicating in theacr_values
parameter which ID method is being used and possibly passing other parameters applicable for that ID method. - The client then proceeds to polling the
token_endpoint
which will answer withauthorization_pending
until the end-user has completed the authentication, at which point the usual token response is returned, containingid_token
andaccess_token
etc. - The client may then optionally use the
access_token
to call theUserInfo
endpoint if needed, or skip this step if theid_token
already contains the required information.
More details in the OIDC official documentation
- Backchannel request parameters (opens new window) Note that not all parameters are supported by all ID methods.
- Possible responses from the token endpoint (opens new window).
# Setting up an OIDC client for CIBA
In the Dashboard, select open OIDC clients > Add client and set Primary grant type to CIBA, and add the scopes you need.
After that, you add a secret to your client and then perform any additional configuration you would like to do.
# ID methods that support CIBA
You can use the buttons below to explore the current list of ID methods that support CIBA.
# Example using Swedish BankID
# The backchannel endpoint
The URL of the backchannel_authentication_endpoint
is found in the discovery metadata, so if your domain with Signicat is yourdomain
then the metadata can be found at https://yourdomain.signicat.com/auth/open/.well-known/openid-configuration
and the backchannel_authentication_endpoint
will point to https://yourdomain.signicat.com/auth/open/ciba
.
The call to the CIBA endpoint will be a HTTP POST with content-type application/x-www-form-urlencoded
, and the call will be authenticated with Basic authentication and the following parameters
login_hint = endUserIp:127.0.0.1 flow:QR
(127.0.0.1 is obviously an example and must be replaced with the actual public IP address of the end-user.)acr_values = idp:sbid
scope = openid profile nin
In terms of HTTP, the request will look like this:
POST /auth/open/connect/ciba HTTP/1.1
Authorization: Basic ZGV2LW...CamdraTd2
Host: yourdomain.signicat.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
login_hint=endUserIp%3A127.0.0.1%20flow%3AQR&acr_values=idp%3Asbid&scope=openid%20profile%20nin
And the response will be (some headers omitted for brevity):
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
{
"auth_req_id": "5ddc7357-abe0-6940-b4a3-fd6eb3277830",
"expires_in": 120,
"interval": 1
}
To obtain the autoStartToken
for APP_LAUNCH
or the data for the QR
code flow, your application must request it from the token endpoint as described in the following section.
# The token endpoint
From this point on, the flow consists of polling the token endpoint. To do that, we perform HTTP POST calls to the token endpoint with the following parameters
auth_req_id = 5ddc7357-abe0-6940-b4a3-fd6eb3277830
(Theauth_req_id
received in the previous response.)grant_type = urn:openid:params:grant-type:ciba
In terms of HTTP, the request will look like this:
POST /auth/open/connect/token HTTP/1.1
Authorization: Basic ZGV2LW...CamdraTd2
Host: yourdomain.signicat.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 101
auth_req_id=8c65e7e5-f5cc-1b4c-a3f5-9f81985ccc83&grant_type=urn%3Aopenid%3Aparams%3Agrant-type%3Aciba
And the response will be (some headers omitted for brevity):
HTTP/1.1 400 Bad Request
content-type: application/json; charset=UTF-8
{
"error": "authorization_pending",
"error_description": "bankid.584e5929-0d9e-4dc7-9890-921f...f252b",
"error_uri": "https://yourdomain.signicat.com/auth/open/config/errors/authorization_pending"
}
- In the
APP_LAUNCH
flow, theerror_description
contains anautoStartToken
. You can use this to construct the app launch URL. TheautoStartToken
will remain the same for the duration of the session. - In the
QR
code flow, theerror_description
contains the data you need to generate a QR code for the user to scan.
Animated QR code
Swedish BankID uses an “animated QR code” security feature, which means that a QR code is only valid for a very short time (seconds). This means your application must generate a new QR code for each call to the token endpoint, and to continuously update the QR code displayed to the end-user. In such scenarios, a polling interval of 1-2 seconds is recommended.
Your client should continue to poll the endpoint as long as the response is an HTTP 400 with error
equal to authorization_pending
. The token endpoint will respond like this:
- If the user cancels the process, the response will be an HTTP 400 with error
access_denied
. - If the user takes too long to complete the process, the response will be an HTTP 400 with error
expired_token
. - If the user has still not fully completed the authentication, the response will be an HTTP 400 with error
authorization_pending
. - And when the user has successfully completed the process, the response will be an HTTP 200 with the usual token response, including
id_token
andaccess_token
.
# Code example
The following is a simplistic Python example of a function that will first call the backchannel endpoint and then make one call to the token endpoint, printing out both responses:
def ciba(end_user_ip, flow='QR'):
# First the backchannel call
url = base_url + '/auth/open/connect/ciba'
headers = {
'Authorization': 'Basic ZGV2LWNs...amdraTd2',
'Content-Type': 'application/x-www-form-urlencoded'
}
data = {
'login_hint': 'endUserIp:' + end_user_ip + ' flow:' + flow,
'acr_values': 'idp:sbid',
'scope': 'openid profile'
}
http_response = requests.post(url, headers=headers, data=data)
ciba_response = json.loads(http_response.content)
print(json.dumps(ciba_response, indent=4))
# And then the token endpoint call
url = base_url + '/auth/open/connect/token'
data = {
'auth_req_id': ciba_response['auth_req_id'],
'grant_type': 'urn:openid:params:grant-type:ciba'
}
http_response = requests.post(url, headers=headers, data=data)
token_response = json.loads(http_response.content)
print(json.dumps(token_response, indent=4))
Running the function produces the following output:
{
"auth_req_id": "9761e8e8-a38b-2e40-a7bd-730805ef9e70",
"expires_in": 120,
"interval": 1
}
{
"error": "authorization_pending",
"error_description": "bankid.3a047f6a-5e7b-41...8faf1db5e892",
"error_uri": "https://yourdomain.signicat.com/auth/open/config/errors/authorization_pending"
}
# A note about the flow options
In the example above, we exclusively used the QR
flow. The other option is the APP_LAUNCH
flow which will – instead of the BankID QR code data, return the autostarttoken
from BankID that you can use to launch the BankID app in “same-device” scenarios. For more information, please see https://www.bankid.com/en/utvecklare/guider/teknisk-integrationsguide/programstart (opens new window).