Embedded Login
Use this API if you need to embed the login user interface in your application. When embedded login is used, the credentials are entered directly into your app and then sent directly to this API. Embedded login also enables the use of external applications for authentication (e g BankID) using the process
-method detailed below. The API can be used from a regular server-side web app, a single-page app or a native app.
This API also support an OAuth-style redirect method where the user is redirected to the login service where credentials are entered and validated and then redirected back to your application.
This API differs from OAuth in that it enables rich embedded login without requiring redirecting to an external identity provider. The API is also flexible in that is allows elevation of the implicit method to a redirect or process method when needed or by configuration, e g if the user is signing in from a new location, when anomaly is detected or when an external identity provider has been configured.
The design of the process
and redirect
methods is equivalent to the proven authorization code flow in OAuth; authentication results in an authorization code that is exchanged for tokens. The design also implements the Proof Key for Code Exchange (PKCE) extenson of OAuth as a required feature.
IMPORTANT: The client requirements specified in OAuth 2.0 Security Best Current Practice and RFC-6819 MUST be implemented.
Sign-in
Use this function to sign in a person or organisation that has previously acquired an account.
This function returns an access token if the sign-in could be completed immediately without further interaction (implicit method), otherwise the sign-in process is considered started and a redirect request (redirect method) and optionally a process reference (process method) is returned that allows it to complete.
Implicit method If completed
is returned, the sign-in was completed immediately. This usually happens when the method password
or refreshToken
is used, but not always due to suspicious activity, account lock-out, configuration, and similiar (se Redirect method below).
Process method If a process
is returned and your client support the process feature, your client should poll the status of the authentication process until it either fails or completes. Please see the Process function below.
Redirect method If a redirect
is returned, please redirect the user to the provided redirect
address. Redirect method may be returned if a external identity provider is configured or for other reasons. Please note that this may also happen if you perform a request that normally always return a process value, for example when suspicious activity is detected. If the sign-in process completes, the browser will be redirected back to the returnAddress
provided in your initial request, se Handling redirect callback below.
When authentication is completed, the access token is sent to all api endpoints as an Authorization header:
IMPORTANT: The access token MUST NOT be stored on disk. If the user closes the browser or application, the access token MUST be erased/lost. Store the access token in memory or in sessionStorage if you are building a SPA (single-page application). See Maintaining session below for further information on how this relates to the refresh token. Do not include the access token, refresh token or an id token as part of a url (including as a query parameter or as a fragment #) to prevent them from being stored in the browser´s history.
IMPORTANT: Tokens MUST NOT be sent to third party services/APIs, that is, tokens shall only be sent directly to the Momentum Fastighet API server. The client MUST at all times validate the certificate of the Momentum Fastighet API server (use HTTPS) and ensure that an attacker cannot inject or alter the address of the PM API server. In addition, tokens MUST only be sent over secure transports, such as HTTPS.
Maintaining session
A client or server/gateway MUST NOT store passwords. To maintain a session for a longer time than an issued access token allows, please request a refresh token using the requestRefreshToken
parameter with method federated
or password
. The refresh token is a secret and should be stored in a single location, on the client only and not on a server. Please use a secure storage mechanism when available. In a SPA, the refreshToken should typically be stored in localStorage (or using a more secure storage method when available). A refreshToken may not always be returned when requested due to policy or anomaly detection.
The refresh token can be used to request a new access token using the refreshToken
method. When a new access token is returned using this method, a new refreshToken is also returned that replaces the old refresh token to prevent token replay. The old refresh token must not be used again and doing so may trigger anomaly detection. Never perform more than one auth request at a time using method refreshToken
to avoid race conditions.
A refresh token may be revoked at any time due to user initiated sign out or other reasons, e g when anomaly is detected. If the refresh token is invalid or has expired, the api will return an error of type MachineErrorException
. The client must gracefully handle this error and allow the user to start a new login process.
Request
Example
Sign in as a service (service account):
Sign in as a end-user:
POST /v2/auth
X-Device-Id: abcdefgh123456789
X-Forwarded-For: 221.1.1.2
{
"method": "password",
"identifier": "username-here",
"key": "password-here"
}
Sign in with BankID using Momentum Login as presentation:
POST /v2/auth
X-Device-Id: abcdefgh123456789
X-Forwarded-For: 221.1.1.2
{
"method": "federated",
"realm": "bankid.com/test",
"returnAddress": "https://localhost/Momentum.Pm.PortalApi.ExampleSite/"
}
Parameters
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 or is identified as a private network address (e g 127.0.01, 192.168.., ::1, fe80:.., etc).
Name | Description |
---|---|
method | Required Method of authentication: password , federated , or refreshToken |
realm | Required for method federated Identifier of which identity provider to use, for example bankid.com/test . Use the Client Configuration API to determine enabled and configured providers when applicable (see object security/authentication/providers, property realm ). |
identifier | Required for method password Offical number (social security number, company registration number, etc), e-mail or username of user signing in. |
key | Required for method password and refreshToken Password of user or previously issued refresh-token |
returnAddress | Required for method federated and redirect flow 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 in Momentum Fastighet under menu "System / Säkerhet / Applikationer / Installationer / Adresser / Lägg till". |
state | Required for method federated and redirect flow 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. |
responseMode | 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. See Handling redirect callback below for further information. |
nonce | Required for method federated and redirect flow 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 (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. 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. |
codeChallengeMethod | Required for method federated and redirect flow Method of code challenge. Use S256 . Clients MUST NOT use plain as it exposes the code verifier. |
codeChallenge | Required for method federated and redirect flow 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 (e g use Nano ID) 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. |
requestRefreshToken | Set to true to request a refresh token, typically only when requested by the end-user, e g with a "Remember me" checkbox. Please note that a refresh token may not be returned when requested due to configuration, client trust or activity history. |
skipUpdatingLastLogin | Set to true to avoid updating last login for a customer in case of login with a users credentials as an employe |
Response
Example
If redirect flow is choosen:
{
"redirect": "https://localhost/Login-Web/public/providers/federated/se-bankid/?context=l2EinSoTqW5UIpgvRBp4ulwcSEasw"
}
{
"redirect": "https://localhost/Login-Web/public/providers/federated/se-bankid/?context=l2EinSoTqW5UIpgvRBp4ulwcSEasw",
"process": {
"id": "l2EinSoTqW5UIpgvRBp4ulwcSEasw",
"link": "https://localhost/Momentum.Pm.PortalApi.WebHost/v2/auth/process/l2EinSoTqW5UIpgvRBp4ulwcSEasw",
"imageData": "data:image/png;base64, iVBORw0KGg....`",
"openOnDeviceText": "Öppna BankID på den här enheten",
"openOnDeviceUrl": "bankid:///?autostarttoken=95ec8742-f941-44d9-a224-c2dcabf09522&redirect=null",
"openOnDeviceUrlPlatform": {
"ios": "https://app.bankid.com/?autostarttoken=95ec8742-f941-44d9-a224-c2dcabf09522&redirect=http%3A%..."
}
}
}
{
"completed": {
"accessToken": "a35a...",
"refreshToken": "a24f...",
"expiresInSeconds": 1800,
"actor": {
"id": 1234567890123456,
"displayName": "John Doe"
}
}
}
Parameters
Name | Description |
---|---|
redirect | Address to redirect the user agent to |
process | Authentication process if started, see below |
completed | Returned if authentication is completed immediately, see below. |
.process
Name | Description |
---|---|
id | Identity of process |
link | Link to poll current status from |
imageData | Image data, typically a QR-code to be displayed to user |
openOnDeviceText | Text to display on the open-on-device button |
openOnDeviceUrl | Link used to open an external application on the user device |
openOnDeviceUrlPlatform | Dictionary of links used to open an external application on the user device that is specific to a platform, such ios or android |
.completed
Name | Description |
---|---|
accessToken | Access token |
refreshToken | Refresh token |
expiresInSeconds | Time in seconds until the accessToken expires |
actor | Actor information, see below. Available if the signed in account is connected to a registered actor in the system (e g customer, applicant, guarantor, employee, application, system, etc), otherwise null. |
Poll status
Use this function to poll the status of a pending, failed or completed sign-in process. It is important to only poll a completed process once. The second attempt to poll a completed process will always fail.
Request
Example
POST /v2/auth/process?id=l2EinSoTqW5UIpgvRBp4ulwcSEasw
X-Device-Id: abcdefgh123456789
X-Forwarded-For: 221.1.1.2
Parameters
Name | Description |
---|---|
id | Value of process.id returned by /v2/auth (above) |
Response
Example
If pending:
{
"status": "pending",
"message": "Öppna BankID och skanna QR-koden",
"originalStatusCode": "outstandingTransaction"
}
{
"status": "failed",
"message": "The BankID application does not seem to be installed, ple...",
"errorReport": "X-737-206-615",
"originalStatusCode": "startFailed"
}
Parameters
Name | Description |
---|---|
status | pending , failed or completed |
message | Message to be displayed directly to end user |
errorReport | Error report reference that should be displayed to end user |
originalStatusCode | Code received directly from external authentication provider, for internal use only |
authorizationCode | Authorization code used to retrieve token |
Handling redirect callback
In the Redirect method, when the sign-in process completes, the user agent (browser) will be redirected back to the returnAddress
provided in your initial 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: These 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 the
Referer-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 Retrieve token below.
When failed the error
parameter is set and contains the value cancel
if the user explicitly cancels the sign-in process. The value server_error
is returned for internal errors; please display a generic error message when returned. Note that a redirect with error
may not include the state
parameter.
Retrieve token
Use this function to retrieve a token using an authorization code.
Request
Example
POST /v2/auth/token
X-Device-Id: abcdefgh123456789
X-Forwarded-For: 221.1.1.2
{
code: "abcdefg",
codeVerifier: "rU5u5B34NMSOJhFo"
}
Parameters
Name | Description |
---|---|
code | Required Authorization code |
codeVerifier | Required Original codeVerifier used to generate the codeChallenge in the initial call to /v2/auth (above) |
Response
IMPORTANT: If a JWT 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.
Example
{
"accessToken": "a35a...",
"refreshToken": "a24f...",
"expiresInSeconds": 1800,
"actor": {
"id": 1234567890123456,
"displayName": "John Doe"
}
}
Parameters
See .completed above.