Skip to content

OAuth 2.0 Authorization Flow using PKCE

⚠️ UNDER DEVELOPMENT: This feature is under development and not ready for production use. Please use only for testing.

Please note that the base address for this api is the Momentum Login service.

This authorization flow is used to sign in an end-user from a client application, such as an web browser or native app (e g iPhone or indows app) to obtain a access token.

This authorization mechanism uses the Authorization Code Flow with Proof Key for Code Exchange (see RFC7636 for details).

The client starts the flow by using the authorize end-point detailed below. The client then redirects the user to the Momentum Login service where the end-user enter his/her credentials, uses BankID or is forwarded to a third party identity provided such as Azure AD. When authentication completes, the user is redirected back to the client. The client finally uses the token end-point to retrieve an access token that is used to access resources, e g call APIs.

We do not recommend the direct use of these APIs. Please use a library instead and be careful to configure it to at minimum follow the important security considerations listed below.

Register the Application

The application needs to be pre-registered i Momentum Fastighet to obtain the client_id and optionally secrets for confidential clients.

Start Authorization

Start the authentication flow by sending a request to the authorize end-point in the web-browser such as:

IMPORTANT: Review the Security Considerations and considerations listed below before using these API:s.

POST /api/auth/oauth2/authorize
    ?client_id=CLIENTID
    &response_type=code
    &redirect_uri=REDIRECTURI
    &state=STATE
    &nonce=NONCE
    &scope=SCOPES
    &audience=AUDIENCE
    &code_challenge=CODECHALLENGE
    &code_challenge_method=S256

Example:

POST https://domain/login/api/auth/oauth2/authorize?response_type=code&client_id=iap-4ba-630-1&redirect_uri=https%3A%2F%2Flocalhost%3A5000%2Fexplorer%2Foauth2-redirect.html&scope=openid%20profile%20email%20official_id&state=VGh1IE1hciAwMyAyMDIyIDEyOjQ3OjIxIEdNVCswMTAwIChjZW50cmFsZXVyb3BlaXNrIG5vcm1hbHRpZCk%3D&code_challenge=pLGlaLhnaht-umV8NHudx5Ob7qmg2Pq_vECE70bQG20&code_challenge_method=S256

IMPORTANT: The X-Forwarded-For HTTP-header MUST be specified if this API endpoint is called via a proxy or server side code. The header MUST NOT be specified if the API endpoint is called directly from a client, such as a webbrowser or native app.

Please note that the API may not accept calls if the original client ip-address cannot be parsed.

Name Description
client_* Required
The client must always identify it self. Confidential clients must authenticate which requires additional parameters to be included with the request. Please see OAuth Client Authentication.
response_type Required
Type of response, use code (authorization code flow)
redirect_uri Required
Return address that the user agent is redirected to when authentication completes or fails. The return address must be absolute and the fragment component of the address is removed (if present) by the API as required by RFC6749. Query parameter code and error is removed (if present) by the API. An address with the scheme http is not allowed, use https or a custom scheme. The return address must be registered, see the Register the Application-step above.
state Required
Used to prevent CSRF (cross-site request forgery) attacks by ensuring that the response belongs to a request started by the user.
Generate a cryptographically strong random string (e g use Nano ID) for each request. Store it in local storage for later use when handling the callback to your application in the Redirect method.
nonce Recommended
Used to prevent token replay attacks on the client by ensuring that the issued token relates to the initial auth request.

Generate a cryptographically strong random string for each request. Store it in local storage for later use when handling the callback to your application in the Redirect method.

To prevent authorization code injection, the nonce MUST be generated by the client itself. The client MUST NOT allow an attacker to modify the value, e g by accepting a value from an external party such as a part of the url or by an api call.
code_challenge_method Required
Method of code challenge.
Use S256. Clients MUST NOT use plain as it exposes the code verifier.
code_challenge Required
Used to prevent interception attacks, such as if the authorization code is intercepted, it cannot be used since the token exchange relies on this initial challenge. The challenge is generated using method specified by codeChallengeMethod.

For S256 (see RFC7636):
Generate a cryptographically strong random string codeVerifier for each request.
Set codeChallenge = BASE64URL-ENCODE(SHA256(ASCII(codeVerifier)))
Example values:
codeVerifier = "rU5u5B34NMSOJhFo" (do not reuse)
codeChallenge = "b4U_fViY4dAnkf7chANuArk1NuaGNRJhpznsj4q9xJQ"

To prevent authorization code injection, the codeVerifier MUST be generated by the client itself. The client MUST NOT allow an attacker to modify the value, e g by accepting a value from an external party such as a part of the url or by an api call.
scope Use only any of openid, profile, email, official_id, offline_access
response_mode Optional
The value form_post SHOULD be used for server-based webapps. The value query SHOULD be used for PWA (progressive web apps), SPA (single-page applications) and native clients. Method query is used if a value is not provided when response_type is set to code. See Handling redirect callback below for further information.
prompt Optional
Not supported

Handling Redirect Callback

When the user completed the sign-in process, the user agent (browser) will be redirected back to the redirect_uri provided in your initial authorize request with the code and state, or error, parameters set.

The parameters are provided in two ways:

  • Form post: The parameters is included in the body of the the request encoded with x-www-form-urlencoded if the response_mode is set to form_post. The body of the request (and hence the code and state parameters) is not directly available to javascript clients and this method can typically only be used by server-based webapps. For this reason, this response method is more secure than query. The metod query also exposes the code in browser history. The form_post method SHOULD be used for server-based webapps.
  • Redirect with query: The parameters is included as query-paramerets if response_mode is set to query.

IMPORTANT security considerations:

  • The state parameter MUST be validated against the previously genererated and stored state (sent as state in the initial request). If the received value doesn't match the initially generated value, the redirect must be rejected. This prevents CSRF attacks.
  • The client MUST genererate a new state value for every request and clear the state value after it has been used (when callback is complete)
  • Servers that handle the redirect callback MUST NOT expose open redirectors (see IETF draft), e.g. accept a ?redirect_url= as part of a url. See Unvalidated Redirects and Forwards by OWASP for further information.
  • The page that handles the callback SHOULD NOT include third-party resources or links to external sites to prevent referer and information leakage.
  • The client MUST suppress the Referer-header, e.g. by setting the Referer-Policy-header (see Referer policy).
  • The client MUST NOT include the value of state, code, codeVerifier, accessToken, refreshToken or idToken as part of a url (including as a query parameter or fragment #) to prevent them from being stored in the browser´s history.

Use the code parameter to retrieve an access token, see Exchange code for Token below.

When failed the error parameter is set and contains the value: * access_denied if the user explicitly cancels the sign-in process. * server_error is returned for internal errors; please display a generic error message when returned and never the value of the server_error parameter directly since this can be used to inject a message into your application. Note that a redirect with error may not include the state parameter. * user_timedout is returned if the user did not complete the sign-in flow in the alloted time * create_account is returned if the user pressed the Create account button.

Exchange Code for Token

When the client has received a code and performed the critical security checks outlined above, the next step is to exchange the code for an access_token that can be used to call APIs and optionally an id_token that can be used to authenticate and get information about the user on the client.

Request

Example

POST /api/auth/oauth2/token
X-Device-Id: abcdefgh123456789
X-Forwarded-For: 221.1.1.2

grant_type=authorization_code&code=pO7rBia9UU4M4XreESckI5nnZMa7A&client_id=iap-4ba-630-1&client_secret=8G%2FwZoAPI4J%2Bf1UrnoavIzN4ocWRv%2FMM7qZyeMG2%2BQc%3D&redirect_uri=https%3A%2F%2Flocalhost%3A5000%2Fexplorer%2Foauth2-redirect.html&code_verifier=OnLD5FggoY4vB-hiwtwPoJfQ5iUb5hFsX9-pVceVT1M

Parameters

Name Description
grant_type Required
Use authorization_code
code Required
Authorization code
codeVerifier Required
Original codeVerifier used to generate the code_challenge in the intial call to api/auth/oauth2/authorize (above)
client_* Required
The client must provide identification or authentication, please see OAuth Client Authentication.

Response

Example

{
    "access_token": "eyJhbGciOiJ...Pve8",
    "id_token": "eyJhbGciOiJ...GjLN",
    "refresh_token": "UfK2mlOtvs2D3mMIGDYoDER33XqZvY5IkzDuGHuogr4",
    "token_type": "Bearer",
    "expires_in": 3600
}

IMPORTANT security considerations: * If an id_token is returned, the nonce of the JWT must be validated against the previously genererated and stored nonce (sent as nonce in the initial request). If the nonce of the received JWT doesn't match the initially generated, the login attempt must be rejected. * Verify that the id_token contains an aud-claim (audience) with the value of the client_id assigned to your client. If not matched, the login attempt must be rejected. * Review the Security Considerations before using these API:s.

This endpoint does not return errors as definied by the Momentum Fastighet API, instead it follows RFC7521.

Example:

{
    "error":"invalid_grant",
    "error_description":"Audience validation failed"
}

Note that the error_description is not intendent to be displayed to the end user.