Authorization Code Flow

We recommend Authorization Code flow for retrieving user tokens in server side applications, this ensures that no access tokens are sent to the browser.

If you are writing a native or single-page applications that can not store a client_secret securely we recommend Authorization Code with PKCE.

Authorize request

Initiating an authorization code flow is done with a GET /connect/authorize request. You provide your client_id, the required scope together with a redirect_uri where the authorization code will be returned. Make sure that response_type is set to code. This will cause the authorization request to return a code parameter to the endpoint given in redirect_uri, you will use the value of this in the following token request.

GET /connect/authorize

requestresponse
Copy
Copied
GET https://id.aritma.io/connect/authorize?scope=SCOPE&response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https://YOUR_APP/callback&state=STATE HTTP/1.1
Copy
Copied
HTTP/1.1 302 Found
Location: https://YOUR_APP/callback?code=AUTHORIZATION_CODE&state=STATE
Parameter Description
scope (required) The scopes which you want to request authorization for. These must be separated by a space. You can request any of the standard OpenID Connect (OIDC) scopes about users, such as profile and email, or any scopes supported by the target API (for example, banking.ais.read). Include offline_access to get a Refresh Token.
response_type (required) Indicates to Aritma ID which OAuth 2.0 flow you want to perform. Use code for Authorization Code Grant Flow.
client_id (required) Your application's ID.
state (recommended) An opaque value the application adds to the initial request that Aritma ID includes when redirecting the back to the application. This value can be used by the application to prevent CSRF attacks.
redirect_uri (required) The URL to which Aritma ID will redirect the browser after authorization has been granted by the user.
prompt To initiate a silent authentication request, use prompt=none, to force user interaction use prompt=login.
acr_values One or more values that controls how the authentication process is, use mfa to force a user with an active session to re-enter his/her/their mfa token (must be used together with prompt=login). See Authentication Context Class References

Token request

Once you have received your authorization code it's time to translate it into a usable access token. This is done using the /connect/token endpoint. In short you send a token request with grant_type=authorization_code together with the supplied code, your client_id and client_secret, and the redirect_uri you provided in the authorization request.

POST /connect/token

RequestResponse
Copy
Copied
POST https://id.aritma.io/connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&code=AUTHORIZATION_CODE&redirect_uri=https://YOUR_APP/callback
Copy
Copied
HTTP/1.1 200 OK
Content-Type: application/json
{
  "access_token":"eyJz93a...k4laUWw",
  "refresh_token":"GEbRxBN...edjnXbL",
  "id_token":"eyJ0XAi...4faeEoQ",
  "token_type":"Bearer",
  "expires_in":86400
}
Parameter Description
grant_type (required) Denotes the flow you are using. For Authorization Code, use authorization_code.
client_id (required) Your application's Client ID.
client_secret (required) Your application's Client Secret.
code (required) The Authorization Code received from the initial /connect/authorize call.
redirect_uri This is required only if it was set at the GET /authorize endpoint. The values must match.

Code example

The following example shows a minimum implementation of a full authorization flow in .net 6.0+. Keep in mind that there are Nuget packages that will help you make more robust authorization and token requests. We recommend Microsoft.AspNetCore.Authentication.OpenIdConnect.

Copy
Copied
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

var CLIENT_ID = app.Configuration["Identity:ClientId"];
var CLIENT_SECRET = app.Configuration["Identity:ClientSecret"];

app.MapGet("/", (HttpRequest request) => {
    var uriBuilder = new UriBuilder("https://id.dev.aritma.io/connect/authorize");
    var query = new QueryString()
        .Add("response_type", "code")
        .Add("client_id", CLIENT_ID)
        .Add("scope", "bankservice")
        .Add("redirect_uri", $"{request.Scheme}://{request.Host}/callback");
    uriBuilder.Query = query.ToUriComponent();
    return Results.Redirect(uriBuilder.ToString());
});

app.MapGet("/callback", async (HttpRequest request) =>
{
    var code = request.Query["code"];

    var tokenClient = new HttpClient() { BaseAddress = new Uri("https://id.dev.aritma.io") };
    var response = await tokenClient
      .PostAsync("/connect/token",
        new FormUrlEncodedContent(
            new Dictionary<string, string>
            {
                { "grant_type", "authorization_code"},
                { "client_id", CLIENT_ID},
                { "client_secret", CLIENT_SECRET},
                { "redirect_uri", $"{request.Scheme}://{request.Host}/callback"},
                { "code", code }
            }
        )
      );
    var tokenResponse = await response.Content.ReadFromJsonAsync<Dictionary<string, object>>();
    var accessToken = tokenResponse["access_token"].ToString();

    // Do your api call here, or store token in session for later api calls.
    // This is an example request that lists all companies the user can access:
    var apiClient = new HttpClient() { BaseAddress = new Uri("https://bankservicedemo.zdata.no") };
    apiClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
    var apiResponse = await apiClient.GetAsync("/api/v3/companies");
    var companyResponse = await apiResponse.Content.ReadAsStringAsync();
    return Results.Ok(companyResponse);
});

app.Run();