OAuth2 Authentication Flow

Among other things the trust relationship of OAuth2 (between client and provider) is based on knowledge of trusted “redirect urls”. These are endpoints made available by the client where an OAuth2 provider will redirect to after he’s authenticated a user. In most cases, Redirect URLs are setup only once and will not change afterwards.

The problem with hardware devices installed at our customers’ homes is that we cannot rely on domain- or hostnames as parts of redirect URLs. Similar devices may be addressed in a totally different way by our customers. Additionally, some mobile platforms don’t provide a way to address specific eitherway.

To mitigate this problem, myBUSCH-JAEGER / MyBuildings portal and its API should act as a intermediary between hard- and software implementations that cannot provide a predictable redirect URL and the OAuth2 provider implementation in order to ensure a steady redirect URL and therefore enable a working OAuth2 request flow.

Glossary

  • SSO: Single Sign-On

  • Portal: myBUSCH-JAEGER / MyBuildings portal

  • Authorization server / : OAuth2 implementation of portal (see RFC6749, 1.1)

  • Access token: Token that is used to authenticate against the portal API (see RFC6749, 1.4)

  • Authorization code: Token that is used to obtain an access token from the portal (see RFC6749, 1.3.1)

  • Refresh token: Token that is used to obtain a new access token if the old one expired

  • Authentication endpoint: Endpoint/URI the portal redirects back to after successful login

  • Frontend-Domain: Used in code examples below, references the Portal’s Web-Frontend domain

  • API-Domain: Used in code examples below, references the Portal’s API domain

Frontend-Domain

The architecture documents and code examples below reference the portal’s frontend with frontend-domain. You don’t need to interact directly with the portal’s web frontend. These domains are here for reference only. The frontend is available at:

Production environment

  • eu.mybuildings.abb.com

API-Domain

The architecture documents below reference the API’s domain with the short term api-domain. We provide multiple environments of the portal. Please choose the correct environment and domain on your own. Therefore, please replace api-domain in the code examples below with one of the following domains:

Production environment

  • api.eu.mybuildings.abb.com

Request flow

The portal supports the following grant types:

  • Authorisation Code Grant

  • Refresh Token Grant

In order to initiate a OAuth2 grant, a device first needs to obtain an authorization code.

The OAuth2 helper for third party applications offers two ways to get an authorization code:

  • Get an OAuth2 helper configuration + Obtain authorization code using a steady request flow

  • Get an OAuth2 helper configuration + Obtain authorization code using a polling approach

In either case, the two ways share a single starting point:

1. Get an OAuth2 helper configuration

POST /external/oauth2helper/config/{client_id}?redirect_url=OPTIONAL

See step 1 in the pictures below (2.1 or 2.2).

To initiate a OAuth2 request flow, the device sends a HTTP POST request to this API endpoint. myBUSCH-JAEGER / MyBuildings portal will generate state parameter that is a) unique, b) signed using JWT and c) bound to the client that originally sent the request.

The device needs to pass the following parameter to the API endpoint:

  • client_id, as part of the path

  • redirect_url (OPTIONAL), as a query parameter

The request will be answered with a JSON document that contains the following parameters:

  • code_url

  • authorize_url

  • accesstoken_request_url

The parameter code_url contains the URL the device must repeatedly check in order to get the authorization code (see 2.2 for more information).

The parameter authorize_url contains the URL authorization endpoint of myBUSCH-JAEGER / MyBuildings portal. The device must redirect the user to this endpoint.

The parameter accesstoken_request_url contains the URL for the SSO’s Access Token Request endpoint of the portal (see 3. for more information).

Example:

curl -XPOST https://api-domain/external/oauth2helper/config/43165bfb-f28c-4325-a1b9-7eedf8766c0f?redirect_url=http://192.168.1.234/code/bje-fhapi-sso-linking.php

Example response body:

{ 
"authorize_url":"https://frontend-domain/sso/authorize?response_type=codeu0026client_id=43165...u0026state=eyJhbGciOiJ...",
"code_url":"https://frontend-domain/external/oauth2helper/code/get/43165...?state=eyJhbGciOiJSUzI1NiIsInR..."
"accesstoken_request_url": "https://frontend-domain/sso/token"
}

2.1. Obtain authorization code using a steady request flow

Only applicable, if the device provided a redirect_url as query parameter in step 1.

The redirect_url may contain an endpoint that is only accessible within the local network, e.g. http://192.168.1.234/code/bje-fhapi-sso-linking.php. If given, the redirect_url should be able to retrieve the query parameter code (an authorization code) at the provided URL.

The device needs to extract the query parameter code from the redirect_url. See step 5 in the picture above.

2.2. Obtain authorization code using a polling approach

In cases where it’s not possible to provide a redirect_url in step step (POST request), the device needs to check for an authorization code on a regular basis.

GET /external/oauth2helper/code/get/{client_id}?state={state}

See step 5 in the picture above.

This endpoint corresponds to the code_url provided in the response to the initial POST request. Devices should use this API endpoint to regularly check for the existance of an authorization code. As authorization codes are short lived (30 to 60 seconds), this API endpoint needs to be checked repeatedly (e.g. every 5 to 10 seconds).

If an authorization code was not yet made available by an OAuth2 provider, or the provider doesn’t exist, the server will respond with HTTP status code 404 (“Not Found”).

If an authorization code was provided, the server will respond with HTTP status code 200 (“OK”) and a JSON document containing the authorization code provided.

Example request:

curl -XGET https://api-domain/external/oauth2helper/code/get/43165bfb-f28c-4325-a1b9-7eedf8766c0f?state=DEFGHI...

Example response body:

{ 
"code": "mnopq67890"
}

After an authorization code has been obtained from this API endpoint, devices need to stop to poll for new authorization codes.

3. Obtain an access token based on authorization code - /sso/token

POST /sso/token

This endpoint is used to obtain an access token for the logged in user.

Example:

curl -v https://frontend-domain/sso/token \ 
-X POST \
-d 'grant_type=authorization_code' \
-d 'code=2cc098ab8b717d3df47ab05c7505e3aa1ec2fec6' \
-d 'client_id=OAUTH2_CLIENT_ID' \
--data-urlencode 'client_secret=OAUTH2_CLIENT_SECRET' \

NOTE: An additional --data-urlencode 'scope=SCOPE' may be required as well, depending on the use-case. Otherwise an empty scope is used.

Response:

{ 
"access_token":"eyJ0eXAiOiJK...",
"expires_in":3600,
"token_type":"bearer",
"scope":null,
"refresh_token":"efa2b46e33c0a9f553c1affc6ca0a2b5321827c1"
}

Applications should store the response content in the current user’s session. Additionally, the refresh token should be saved for later use (when an access token expired and it’s necessary to get a new one).

4. Get a new access token – /sso/token

As seen in the response content of the API call to /sso/token, access tokens have a limited lifetime of 3600 seconds.

Applications should check on a regular basis if the access token has expired.

If the access token has reached its expiration, applications can obtain a fresh access token by sending additional requests to /sso/token - this time, sending a refresh token instead of an authorization code.

Example:

curl https://frontend-domain/sso/token \ 
-X POST \
-d 'grant_type=refresh_token' \
-d 'client_id=OAUTH2_CLIENT_ID' \
--data-urlencode 'client_secret=OAUTH2_CLIENT_SECRET' \
-d 'refresh_token=efa2b46e33c0a9f553c1affc6ca0a2b5321827c1'

Response:

{ 
"access_token":"eyJ0eXAiOiJK...",
"expires_in":3600,
"token_type":"bearer",
"scope":null,
"refresh_token":"8843d7f92416211de9ebb963ff4ce28125932878"
}