Authentication for User App

userapp can authenticate with fabric Identity in one of the 2 ways:

Using Authorization Code Flow with PKCE (recommended)

To initiate this authentication flow, the following details are needed (for more information see here)

client-id - This is a unique ID that represents the userapp and is required for OpenID Connect authentication flows

Authorization Url - This is the http end point of fabric Identity that the app needs to communicate with for getting its access token.

Once the above details are available, proceed with building the authentication flow as depicted below:

Authentication Flow with PKCE

1. Generate PKCE code verifier and code challenge

In this step, the single page app or a mobile app, represented by the respective userapp in fabric Identity, generates a code verifier and a code challenge from the code verifier. These codes ensure that the access token returned by fabric Identity (in step #8) is returned to the correct requestor.

code-verifier: Random URL-safe string with a minimum length of 43 characters. See here for more details

code-challenge: Base64 URL-encoded SHA-256 hash of the code-verifier

The app should store the code-verifier securely to be used later (in step #6). The code-challenge is sent earlier in the call to the /authorize endpoint (in step #2)

2. Authorization Code request with code_challenge

In this step, the app should prepare a GET request to fabric Identity's /authorize endpoint and load the GET url into the window.location. This will allow fabric Identity to send a browser re-direct and take the end user to the hosted login page.

Here is a representation of the URL that should be constructed and loaded into window.location

https://${Authorization Url}/v1/authorize?client_id=${client-id}&response_type=code&scope=openid&redirect_uri=${redirect-uri}&state=${state}&code_challenge_method=S256&code_challenge=<sha256(${code-verifier})>
  • Authorization Url : This is the url made available upon creating a userapp . See Getting Started for more details.
  • client-id : Unique ID created for the userapp . See Getting Started for more details.
  • redirect-uri : This is the URI that fabric Identity will redirect to after a successful authentication. This should a URI of the requesting userapp and will contain a temporary authorization code (see step #5). The app should be prepared to use the query parameters on the redirect-uri and then complete the authentication flow with fabric Identity
  • state : An opaque value (can be a random string) used by the app to maintain state between the request and callback from fabric Identity. This parameter is tyically used for preventing cross-site request forgery. See here for more information.
  • code_challenge : This query parameter in the above URL is a SHA256 hash of the code-verifier . See here for more details.

3. fabric Identity send 302 redirect to authentication prompt

As a response to step #2, fabric Identity would sent a redirect to the client browser to bring up the hosted login page. This hosted login page can also be configured for social logins, sign-up and forgot password links.

4. Enter credentails & provide consent

This is an action by the end users to successfully provice their identity. If configured, they would also provide consent tp fabric Identity to share their basic profile information with the calling app.

5. Authorization Code response sent back to the given redirect uri

After a successful login, fabric Identity would redirect the end user back to the redirect-uri shared in the step #2. As part of this redirect, fabric Identity sends the following additional details as query parameters:

  • code : The authorization code, a temporary code which should be returned back to fabric Identity along with code-verifier to get an access token
  • state : The same state send by the app to fabric Identity in step #2

6. Send authorization code with code_verifier

Once the app receives the redirect from fabric Identity it should validate if the state field matches with the one sent in step #2. After this, the app should use the code and make a POST request to fabric Identity to fetch the access token.

Below is an example of the POST request (represented as a curl command)

curl --request POST \
  --url https://${Authorization Url}/v1/token \
  -H 'accept: application/json' \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code'
  -d 'client_id=${client-id}'
  -d 'redirect_uri=${redirect-uri}'
  -d 'code=${code}'
  -d 'code_verifier=${code-verifier}'
  • Authorization Url : This is the url made available upon creating a userapp . See Getting Started for more details.
  • client-id : Unique ID created for the userapp . See Getting Started for more details.
  • redirect-uri : This is the same URI that was originally sent by the app to fabric Identity in the step #2
  • code : The authorization code received by the app in step #5
  • code-verifier : The original code-verifier generated by app in step #1

7. Validates Code Verifier

Once the POST request is received on its /token endpoint, fabric Identity validates the code-verifier by computing its SHA256 value and verifies this against the code-challenge sent by the app in step #2. Upon successful validation it return the response with the access token i it.

8. Respond back with access token

Upon successful validation of the code-verifier, fabric Identity returns the response with the access token.

Below is an example of a successful response from fabric Identity

{
    "access_token": "eyJhbGciOiJ...",
    "expires_in": 3600,
    "id_token": "eyJhbGciOiJI...",
    "refresh_token": "cBMrwDsXRwPqVmCQx7I5IX0jQ9-Lc_zHOgYeab1xZm4"
    "scope": "openid offline_access",
    "token_type": "Bearer"
}

The access_token returned in the response above is a user token and would have a default expiry of 30 minutes (3600 seconds). This token should be used as a bearer token by the app to invoke fabric's APIs.

Also note that the response contains a refresh_token. The refresh_token can be used by the app to fetch a new access_token once the previous one expires.

9. Request fabric platform API using access token as a bearer token

The app can now invoke any of the fabric API using the access_token received in the previous step. This token should be sent in the Authorization header as a Bearer token which is then validated by the fabric API.

App developers can use 3rd party libraries (see here for an example) to achieve the above authentication flow.

Using Authorization Code Flow

TBD

Refresh Access Token

User tokens generated by fabric Identity have a default expiry of 30 minutes. Refresh tokens on the other hand are longer-living tokens and can be used to retrieve new access tokens without asking the end user to login again. For security reasons, every time a refresh token is used to get a new access token, the previous refresh token is discarded and a new one is recreted. Refresh tokens are also discarded if not used for 7 days. In such a cases the app should follow the previous authentication flow and allow end user to login again.

New access token can be requested from fabric Identity using a refresh token in a single step. Below is an example http call that the app can make to get a new access token from a refresh token:

curl --location --request POST 'https://${Authorization Url}/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'redirect_uri=${redirect-uri}' \
--data-urlencode 'scope=offline_access openid' \
--data-urlencode 'refresh_token=${refresh-token}' \
--data-urlencode 'client_id=${client-id}'
  • Authorization Url : This is the url made available upon creating a userapp . See Getting Started for more details.
  • client-id : Unique ID created for the userapp . See Getting Started for more details.
  • redirect-uri : This is the same URI that was originally sent by the app to fabric Identity in the step #2 of the authentication flow.
  • refresh-token : Refresh token received by the app along with the access token.

Below is a sample response sent from the fabric Identity for the refresh request:

{
    "token_type": "Bearer",
    "expires_in": 3600,
    "access_token": "eyJraWQiO...",
    "scope": "offline_access openid",
    "refresh_token": "jSdVOtddMk8HMHP...",
    "id_token": "eyJraWQ..."
}

Note that the response contains a new access_token along with a new refresh_token.