- 05 Nov 2024
- 4 Minutes to read
- Print
- DarkLight
- PDF
Server-Side Web Applications
- Updated on 05 Nov 2024
- 4 Minutes to read
- Print
- DarkLight
- PDF
A server-side web application must implement the authorization_code OAuth 2.0 grant type. For compliance with OAuth 2.1 specifications, a web application can also be configured to use Proof Key for Code Exchange extension. This can be enabled or disabled in the application's details page.
In order to authenticate users in a server-side web application, follow the steps described below.
Step 1: Authorization request
Before starting the authorization process, applications with PKCE enabled create what is known as the code verifier. This is a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.
Once the app has generated the code verifier it uses that to create a code challenge. The code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier.
Initiate the authorization process by redirecting the user to Visma Connect authorization endpoint. This endpoint is accessible over https; plain http connections are refused. Ensure query parameter values are always URL encoded. The set of query parameters supported by the Visma Connect Authorization Server include:
Name | Example Value | Required | Description |
---|---|---|---|
client_id | demoapp | yes | The Client ID set when application was registered. Identifies which app is making the request. |
scope | openid email profile offline_access visma_api:read The “visma_api:read” scope-name above is just an example - check your API documentation for scope(s) to use. | yes | Identifies the user information that your application is requesting. One scope openid is required. The values passed in this parameter inform the consent screen that is shown to the user. Note: If your application is configured with Offline Access, you can include the offline_access scope to get |
redirect_uri | https://demoapp.example.com/oauthcallback | yes | Determines where the OAuth Callback response is sent back to your application. The value of this parameter must exactly match the value added on application registration. This includes the https scheme, the same case. |
code_challenge | The code challenge generated | yes, when PKCE enabled | Base64-URL-encoded string of SHA256 hash of the Code Verifier. |
code_challenge_method | S256 or plain | yes, when PKCE enabled | Whether the challenge is the SHA256 hash of the string or the plain verifier string. |
response_type | "code" or "code id_token" | yes | Determines whether the OAuth 2.0 endpoint returns an authorization code and possibly an id_token. If Hybrid Flow is enabled, the value must be set to "code id_token" |
nonce | qksKW97hcv | yes, for Hybrid Flow | Nonce (Number Only used once). A string value which will be included in the response from Visma Connect, used to prevent token replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token. If present in the ID Token, the application must verify that the nonce value is equal to the value of the nonce parameter sent in the Authentication Request. If the nonce value has already been received and used, the Application must not accept it. If Hybrid Flow is enabled, a nonce value is required. |
state | This field can be a Base64 encoded JSON object that can hold multiple values | no | Authorization protocols provide a state parameter. During authentication, the application sends this parameter in the authorization request, and the Authorization Server will return this parameter unchanged in the response. Your application can use this parameter in order to make sure that the response belongs to a request that was initiated by the same user. Therefore, state helps mitigate CSRF attacks. Restore the previous state of your application. Read more |
response_mode | form_post or query | no | Specifies how response parameters are returned to the client, by posting a form or in a query string. Default and recommended way is form_post. |
ui_locales | nb-NO sv-SE en-GB | no | End-User's preferred languages and scripts for the user interface, represented as a space-separated list of BCP47 [RFC5646] language tag values, ordered by preference. Values currently supported:
|
tenant_hint | 604ad704-772a-46f7-8926-571769f067e7 | no | Tenant ID (context) for Applications doing authorization of user-roles as part of Visma Connect. |
Example:
GET https://connect.visma.com/connect/authorize?client_id=demoapp&response_type=code+id_token&response_mode=form_post&scope=openid+email+profile&redirect_uri=http://demoapp.example.com/oauthcallback&nonce=qksKW97hcv&state=CfDJ8NbGuiMeKnBKlosjbaGWcBzxsyHJjSmlXdcP5HT0Jp_qH...tE8u1Ws&ui_locales=nb-NO+sv-SE+en-GB
Step 2: User consent
In this step, the user decides whether to grant your application the requested access or not. At this stage, Visma Connect displays a consent window with the name of your application, seeking permission to access with the user’s authorization credentials. The user can then consent or refuse to grant access to your application.
Your application doesn’t need to do anything at this stage as it waits for the response from Visma Connect Authentication server indicating whether the access was granted or not.
Step 3: Authentication Response
Since we requested a form POST as response (response_mode=form_post used on the request), the authorization server sends the following response back to your application:
POST https://demoapp.example.com/oauthcallback Content-Type: application/x-www-form-urlencoded code: 94c99b73c13c1e39f7b0a7d259628338 &id_token:eyJhbGciOiJSUzI1NiIsImtpZCI6IjZCN0FDQzUyMDMwNUJGREI0R...ZBMEu6dA &scope:openid email profile &state:CfDJ8NbGuiMeKnBKlosjbaGWcBzxsyHJjSmlXdcP5HT0Jp_qH...tE8u1Ws &session_state:u9pDw26xhANhsj5vmg9aClWqWPRx8OdbyScowPzd8d0.4febcb64e04a793c4ab1aec3f1392257
Here are the details of received parameters:
code: Authorization Code to be used to retrieve and access token
id_token: JWT token containing user's identity. Nonce specified in request is in this token and can be validated
scope: Scopes specified in request
state: State specified in request
session_state: Session state (string) that together with client_id can be sent to the /connect/checksession endpoint to validate session at IdP
Step 4: Exchange Authorization Code for Tokens
After the app receives the authorization response, it exchanges the code for an Access Token and ID Token. Sample request:
curl --request POST --url https://connect.visma.com/connect/token --header 'content-type: application/x-www-form-urlencoded' --data 'grant_type=authorization_code&redirect_uri=https%3A%2F%2Fdemoapp.example.com/oauthcallback%2Fcallback&code=94c99b73c13c1e39f7b0a7d259628338&client_id=demoapp&client_secret=SECRET'
Parameters:
Name | Example Value | Required | Description |
---|---|---|---|
grant_type | authorization_code | yes | As defined in the OAuth 2.0 specification, this field must contain a value of authorization_code. |
redirect_uri | https://demoapp.example.com/oauthcallback | yes | The same value used on the authorization request. |
code | 94c99b73c13c1e39f7b0a7d259628338 | yes | The authentication code returned from the initial request. |
client_id | demoapp | yes | The Client ID set when application was registered. Identifies which app is making the request. |
client_secret | The secret obtained when registering the application | yes | This is your application's Client Secret. |
code_verifier | The generated verifier | yes, when PKCE enabled | The code verifier for the PKCE request, that the app originally generated before the authorization request. |
If successful, this call will return a neatly packaged token that will contain the following fields:
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjVENDc....7MTOBbdd5mgb2CHzxL0RFjs24pqC1pCeUqOjbg",
"id_token": "eyJhbG....dsaeKOJdIHS988MLKJdsaCeUqOjbg",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "openid email profile"
}
When Identity Scopes are used in the authentication request your application can retrieve additional information about the authenticated user from UserInfo Endpoint.
If offline_access scope is used in the authentication request, the response will also contain an refresh_token which can be used to refresh an expired access token.