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 pathredirect_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"
}