The BankID OIDC Service is an identity provider for BankID (netcentric and mobile) via an OpenID Connect (OIDC) interface. |
BankID OIDC is currently in pilot for evaluation purposes and shall not be used for commercial applications |
BankID OIDC consists of a modern industry-standard REST API in front of the regular BankID Service. The REST API is based on OpenID Connect 1.0 being a simple identity layer on top of the OAuth 2.0 authorization protocol. The resulting BankID OIDC Service enables merchants to start using BankID with minimum effort compared to the legacy integration path (ie. install BankID Server, add a BankID merchant certificate and integrate towards the proprietary API of BankID server).
Applications using the BankID OIDC Service are hereafter referred to as BankID OIDC Clients, as opposed to the legacy term BankID Merchants. Note that BankID OIDC is a multi-tennant service having the capability to host several BankID merchant certificates. In its default configuration all OIDC Clients share a common BankID merchant certificate associated with the BankID OIDC Service itself.
BankID OIDC is an identity provider in its own capacity but is also designed to be an identity provider for Microsoft Azure AD B2C.
BankID OIDC also integrates with a service to provide additional information like private address and phone number for the end-user being authenticated.
The BankID OIDC Service comes with a default GUI experience including dialogues for BankID netcentric and BankID on Mobile along with a selector dialog allowing the end user to choose between these two alternatives. The default GUI experience also contains a consent dialog allowing the user to accept or deny use of any additional user info that the BankID OIDC Service may provide. The default GUI experience is redirect-based, thus hosting the said dialogues on a landing page separate both from the OIDC Client and the OIDC Service. An OIDC Client may however override the default GUI experience and provide its own customized dialogues hosted at any URL.
The following sections describes the BankID OIDC Service in further detail.
The BankID OIDC Service is available in different environments. Please contact developer@bankidnorge.no to request access. See BankID OpenID Connect for further description of configuration information that needs to be supplied.
Example/demo web applications (ie. BankID OIDC Clients), with corresponding source code on GitHub, are available to start exploring the BankID OIDC Service.
prod | preview | pre-prod | protoype | |
BankID OIDC Service | ||||
REST API base URL | na | preview.bankidapis.no/oidc | xxx | |
Example/demo web apps | ||||
C# .NET | na | xxx | ||
Java | na | source code | source code | xxx |
This section outlines how web applications constituting BankID OIDC Clients can obtain a secure BankID authentication of its end users and also let users decide what information/resources the web application gain access to. The below role names are used based on definitions in the OAUTH2 standard (see OAUTH2 RFC6749 and OpenID Specs for more info):
A short description of the protocol steps follows:
Pre condition: Resource Owner starts Client with a request from the User-Agent. The Resource Owner is not previously authenticated.
A: Client redirects the User-Agent to Authorization Server with an authorization request. Parameters to the request identifies Client, lists resources needed (scopes), supplies an URL to where control is to be returned - to name a few.
B: Authorization server triggers display of end-user dialogues to complete authentication. The dialogues shown will depend on any login_hint provided by the Client. BankID OIDC currently supports both BankID på mobil or Banklagret BankID. (Note: The Client is kept out of this dialogue - this is intentional so the Client cannot replay an authentication at a later stage.)
C: Authorization server returns to Client with authorization_code and id_token - if Client is authorized for openid extention. Id_token contains claims with identity info so the Client may know the identity of its user. The authorization_code is used to obtain access to resources
D: The Client requests for an access_token used for sending requests to Resource Server. Client needs to supply with Client_id, client_secret (password), authorization_code, redirectURL (for control purposes) and some more. (Note: This request does not go through the User-Agent. This is a security feature. The client_secret and the returned access_token is not exposed to the User-Agent.)
E: Authrorization Server responds with an access_token and a list of resources (scopes) that are available with the user's consent.
F: The can request resources with the access_token as a proof of authorization (bearer token).
G: Resource Server validates the access_token by caling the introspect endpoint of the Authorization Server and gets metadata from the access_token in return. In case of BankID OIDC this is user information and a list of audience (allowed resources).
Steps F and G can be repeated on several Resource Servers until the access_token expires. (Note: the BankID OIDC Service does currently not support refresh_tokens)
Please see source code on GitHub for examples on how to implement a Client for the BankID OIDC Service.
A BankID OIDC Client will follow these steps to authenticate an end user:
Note: Id_tokens should be validated for security reasons. There are several frameworks for working with OIDC. Some fameworks have automatic support for validating the id_token before getting access to it, and some publish example code for doing so. The published examples may be used as a template.
Below is an example id_token as returned from BankID OIDC Service in pre-production:
{
"kid":"bankid-oauth",
"typ":"JWT",
"alg":"RS256"
}.{
"preferred_username":"Testesen, Test",
"name":"Testesen, Test",
"given_name":"Test",
"family_name":"Testesen",
"sub":"9578-6000-4-127698",
"iat":1485863742,
"iss":"https://preprod.bankidapis.no",
"auth_time":1485863742,
"exp":1485867342,
"birthdate":"1980-03-09",
"nonce":"63621460527719310(abriviated for display)c0NDk1NDIz",
"amr":["BankID"],
"azp":"DotNetClient",
"aud":"DotNetClient",
"c_hash":"SVJo7O-d4cY8N4VgiVwETQ"
}
Please contact developer@bankidnorge.no to request access to the BankID OIDC Service and enroll an OIDC Client.
The following information must be supplied by the application owner to configure the application as a BankID OIDC Client. Sucessfull enrollment will result in the return of a client_id and a client_secret to the application owner.
The BankID OIDC Service currently consists of 6 end-points as further described in the following
https://preprod.bankidapis.no/oidc/oauth/.well-known/openid-configuration
Anonymous requests are allowed.
This end-point returns a JSON-formatted response containing key properties of the BankID OIDC Service.
Among other things this end-point is used to prepare for token validation.
Example response from /openid-configuration
{
"issuer":"https://preprod.bankidapis.no",
"authorization_endpoint":"https://preprod.bankidapis.no/oidc/oauth/authorize",
"token_endpoint":"https://preprod.bankidapis.no/oidc/oauth/token",
"userinfo_endpoint":"https://preprod.bankidapis.no/oidc/oauth/userinfo",
"jwks_uri":"https://preprod.bankidapis.no/oidc/oauth/userinfo/jwk",
"scopes_supported":[
"standard_bankid", "address", "phone",
"nnin", "openid", "profile",
"email"
],
"response_types_supported":[
"code", "token", "id_token",
"id_token token", "code token", "code id_token",
"code id_token token"
],
"response_modes_supported":[
"query", "fragment", "form_post"
],
"grant_types_supported":[
"authorization_code"
],
"subject_types_supported":[
"public"
],
"id_token_signing_alg_values_supported":[
"RS256"
],
"userinfo_signing_alg_values_supported":[
"RS256", "none"
],
"token_endpoint_auth_methods_supported":[
"client_secret_post", "client_secret_basic"
],
"claim_types_supported":[
"normal"],
"claims_supported":[
"preferred_username", "name", "sub",
"iat", "iss", "auth_time",
"exp", "birthdate", "nonce",
"amr", "azp", "bid_code",
"aud", "at_hash", "c_hash",
"nnin", "address", "phone"
],
"claims_parameter_supported":false,
"ui_locales_supported":[
"no",
"en"
],
"login_hint_supported":"[BIM|BID][:\\d{11}][:\\d{8}][:\\d{6}] for respectively client_type, nnin, phoneNo, birthday",
"serverVersion":"bankid-oauth-api 1.2.0"
}
https://preprod.bankidapis.no/oidc/oauth/userinfo/jwk
Anonymous requests are allowed.
This end-point returns the public part of keys used for signing tokens. The keys are later used for token validations.
Example response from /jwk:
{
"keys":[
{
"kty":"RSA",
"n":"khw6L8E9GwwTu5AUclp (abbreviated ...) OM0MdzrKLLrmgiYVi",
"e":"AQAB",
"kid":"bankid-oauth",
"use":"sig"
}
]
}
https://preprod.bankidapis.no/oidc/oauth/authorize
This is a browser redirect end-point that is thoroughly described in the OIDC/OAUTH2 standards. The following query parameters pertaining to the BankID OIDC Service can be used:
Parameter | Comment |
---|---|
client_id bid_client_id | This is a unique ID for the calling OIDC Client. May also use bid_client_id (mandatory when passing through AAD B2C which have its own client_id). |
scope | The discovery endpoint (see example above) returns "scopes_supported":[ profile and email are part of the standard scopes, but are currently not supported by BankID OIDC Servoce address and phone is supported as additional info if the Client is configured to allow for such information. nnin - the Norwegian National Identiy Number (fødselsnummer) is supported as additional info if the Client is configured to allow for this information. A standard_bankid scope is used for clients with default scope of nnin, but currently don’t want nnin to be added in the UserInfo response. |
response_type | Three alternatives (associated with autorization code OAUTH2 flows) are currently supported:
The following alternatives (associated with implicit OAUTH2 flows), are currenly not supported:
|
response_mode | This is how the response redirect is done. These alternatives are supported: query, fragment, form_post. Note: The .NET/C# example GitHub uses the OWIN framework. OWIN only accepts form_post response mode. |
login_hint | This parameter may be used to set choice of BankID authentication (netcentric or mobile) and, if known to the Client, nnin, mobile phone no, or birthday of the user. An emtpy login hint implies that the default (or customized) GUI takes care of all interaction with the end-user to determine necessary login details. The discovery/metadata endpoint returns: "login_hint_supported":"[BIM|BID][:\\d{11}][:\\d{8}][:\\d{6}] for respectively client_type, nnin, phoneNo, birthday" Here are some examples with explanation:
In example no 5 the user is prompted for choice of BankID version, but Norwegian national number is used for BID and birthday is used for BIM (first 6 digits). |
ui_locales | May be used to set a language preference for GUI handling. The default GUI experience supports nb (Norsk Bokmål) and en (English) |
Note: When response_type contains both id_token and code, the authorization_code is duplicated into bid_code claim in the id_token to avoid conflict with authorization_code issued by AzureAD B2C. AAD must copy the claims from BankID OIDC id_token to the one issued by AAD. The client must get an access_token from the token end-point of the BankID OIDC Service in order to use resources managed by this service. This includes the UserInfo end-point.
https://preprod.bankidapis.no/oidc/oauth/token
Requires basic authentication with client_id and client_secret in the Autorization header,
This end-point is used for exchanging an authorization_code with an access_token. The access_token is used for accessing resources like userinfo and potential other resource servers. The access_code exchanged was created by the authorization endpoint with a response_type containing "code"
The request should be a POST with parameters sent as "application/x-www-form-urlencoded" data.
Input:
Return is a JSON structure with name/value pairs.
https://preprod.bankidapis.no/oidc/oauth/userinfo
BankID OIDC has implemented an UserInfo enpoint. It is implemented as a resource server and expects an access_token as a Bearer token. There are no parameters. This service is the only way to get the nnin (fødselsnummer) of the authenticated user.
Example response from /userInfo:
{
"sub": "9578-6000-4-127698",
"iss": "https://preprod.bankidapis.no",
"iat": 1485866449,
"exp": 1485870048,
"preferred_username": "Testesen, Test",
"name": "Testesen, Test",
"given_name": "Test",
"family_name": "Testesen",
"birthdate": "1980-03-09",
"nnin": "09038000010"
}
https://preprod.bankidapis.no/oidc/oauth/introspect
In return the resource server get claims from the access_token including its expiration time. The return is in JSON form with a list of name/value pairs.
Resources managed/authorized by the BankID OIDC Service get a “public” access_token (“one access_token to rule them all”). When an OIDC Client uses scope (or default scope) to define what resources it needs authorization for, the issued access_token can be used for all those resources. The resources must call the introspect endpoint in order to verify that it is the correct audience/resource for this access_token as well as getting returned the access_token contents/claims. Resources are expected to cache/cookie this information so there’s no need to call introspect for every incoming request with the same access_token.
The introspect endpoint demands basic authentication with the resource’s client_id and client_secret so that it knows what resource it is dealing with.
Another policy is to have “private” access_tokens. That means each resource has their own access_token issued and encrypted with their client_secret/resource_secret. This would remove the need to call introspect in order to validate and get claims, but it will be difficult for the client to keep track of all the access_tokens issued to individual resource services. AAD is doing this and using the refresh_token to ask for more scope (new resources). This would work as long as the refresh_token is issued for the same resource owner (end-user).
"Private access_tokens" are currently not supported. Refresh_tokens are also not implemented. The rationale is that the supported “public” implementation is considered to more efficient (provided the caching we mentioned).
The current implementation of BankID OIDC has no database to persist tokens. All tokens and session data resides in memory. Persistence is centralized and we aim to utilize database later. HttpSession or cookies are not in use.
The default GUI experience of the BankID OIDC Service can be overridded and replaced by a customized implementation as described in the following.
Please see source code on GitHub for an example on how to implement such a GUI customization. (TODO: Publish such an example)
GUI customization demands that OIDC Client is configured with a specific "presentationURL" paramter with the OIDC Service overriding the URL of the landing page for the default GUI.
Any GUI implementation (called "BidViewer" in the below diagramme) will interoperate with the BankID OIDC Service (the "BINAS Realm") as following:
The authentication alternatives are
The initial request to BidView will contain two parameters:
Here is a list of REST endpoints to be used by BidView (GUI) whith explanations:
Address | Functionality |
---|---|
bimfinished | This is a polling function to be notified when a BankID på Mobil authentication has ended (hopefully with success). Http status code 200 is used to indicate that BankID OIDC has got the terminating "verifyAuth" or "handleError" notifications. Http status code 204 is returned while the authentication is still in process. |
queryGUI | When the BidView (GUI) is called, with sid (session ID) as parameter, it can send a queryGUI request to get session based info in return:
|
startBID | Start the merchant back end session for Banklagret BankID. Input parameters:
Returned parameters:
|
startBIM | Initiate a BankID på Mobile authentication Input:
Returned:
|
consents | When the GUI shall build the consent screen this REST-call is needed to retrieve information. Input: sid -session ID Returned:
|
cancel | This is used for handling the user canceling out of BankID authentication or concent screen notifying BankID OIDC backend. Input is sid - session ID. |
To be able to display a concent screen like the one below, some extra information needs to be stored connected to each scope used by the OIDC Client. BankID OIDC will only give a list of scope names/IDs that requires user's consent. A description for each of those needs to be provided in the appropriate locale.
Norwegian | English |
---|---|
BankID OIDC has been tested with success as an identity provider for Azure AD B2C via a private preview service from Microsoft.
When Azure AD B2C becomes generally available (tentative Q217) this documentation will be updated on how to use BankID OIDC in such a context.
Applications connecting via Azure AD B2C can be offered the same set if services from BankID OIDC as for those applications that integrate directly with BankIDOIDC.
Some notes on usage: