# 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](/apis/platform/ids/flows/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](#token-request). ### GET /connect/authorize ```HTTP request GET https://id.aritma.io/{tenant}/connect/authorize?scope=SCOPE&response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https://YOUR_APP/callback&state=STATE HTTP/1.1 ``` ```HTTP response 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](/apis/platform/ids/acr_values) | ## 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 ```HTTP POST https://id.aritma.io/{tenant}/connect/token HTTP/1.1 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 ``` ```HTTP Response 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](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.OpenIdConnect). ```csharp var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); var CLIENT_ID = app.Configuration["Identity:ClientId"]; var CLIENT_SECRET = app.Configuration["Identity:ClientSecret"]; var TENANT = app.Configuration["Identity:TenantId"]; app.MapGet("/", (HttpRequest request) => { var uriBuilder = new UriBuilder($"https://id.dev.aritma.io/{tenant}/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/{tenant}") }; var response = await tokenClient .PostAsync("/connect/token", new FormUrlEncodedContent( new Dictionary { { "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>(); 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.aritma.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(); ```