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 theresponse_mode
is set toform_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 thanquery
. The metodquery
also exposes thecode
in browser history. Theform_post
method SHOULD be used for server-based webapps. - Redirect with query: The parameters is included as query-paramerets if
response_mode
is set toquery
.
IMPORTANT security considerations:
- The
state
parameter MUST be validated against the previously genererated and stored state (sent asstate
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 thestate
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 theReferer-Policy
-header (see Referer policy). - The client MUST NOT include the value of
state
,code
,codeVerifier
,accessToken
,refreshToken
oridToken
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:
Note that the error_description
is not intendent to be displayed to the end user.