GBG Developers

Guides   |   Delegated Authentication: M2M

Delegated Authentication: M2M

Introduction

Delegated Authentication relies on a standard solution known as OAuth OpenID Connect, offered by providers such as Amazon and Microsoft. GBG servers are not involved in the process; the nature of delegated authentication means that the application trusts the third party and GBG servers will never require visibility to the credentials.

Typically there are two ways to use OAuth with your identity provider. One way is known as browser-based authentication or Single Sign-On (SSO). The identity provider’s web page is used to securely enter your username and password and then control is redirected back into your application.

The other way is referred to as Machine-to-Machine (M2M), or more formally as Client Credentials Grant and it has a simpler message exchange with no web page redirects.

With all OAuth delegated authentication procedures (SSO or M2M), the HTTP interaction between your application and the provider will result in an IDP access token being returned. The IDP access token will then be used to obtain a GBG access token, which provides access to the Identity Solution.

The M2M method of delegated authentication means that the first HTTP request (which is sent to your identity provider) contains a secret value or a certificate. The identity provider will confirm it and send back an IDP access token. Next, your application can send the IDP access token in a HTTP request to the GBG Identity Solution servers. GBG will return back a GBG access token. That token will be valid for performing multiple Identity Solution requests (using SDKs or API). Eventually the GBG access token expires (the IDP access token also typically expires) and you will need to repeat the process.

Your chosen identity provider will have online documentation explaining how to configure their platform for accepting OAuth HTTP requests for delegated authentication.

The M2M method ordinarily uses a pre-shared client secret. You can see an example of this in the Python demo code (see the get_token.py file).  Alternatively a certificate (in a particular format known as JWT) can be used. Both methods are described here using Microsoft Azure as the example identity provider, but always consult the documentation of your chosen identity provider for detail.

 

M2M using Pre-shared Client Secret

To use the pre-shared client secret method, you need to go into your identity provider portal (the screenshot below shows the Microsoft Azure portal) and click on Azure Active Directory -> App Registrations and then select your application, and click on Certificates & secrets settings. A new client secret is then created. That secret needs to be sent in the authentication requests to the identity provider.



The Python demo code get_token.py file can be examined to see the format of the HTTP request that needs to be sent to the identity provider. An example using Postman is shown here:


The key fields are described here:

HTTP POST URL: The URL can be found in your identity provider portal. For Microsoft Azure, navigate to Active Directory -> App Registrations and then click on Endpoints to see a list of URLs. The one you require is called the OAuth 2.0 token endpoint (v2). It will usually end in /oauth2/v2.0/token

grant_type: This field is always set to the text client_credentials

client_id: With Microsoft Azure, this field is known as the Application (client) ID. Other identity providers may name it differently

client_secret: Within the Azure portal, this field is generated by navigating to the App Registrations page, selecting your application and then clicking on Certificates & Secrets and then selecting New client secret

scope: Within the Azure portal, this field is obtained by selecting your application and then ensuring an Application ID URI is present (if it isn’t, you can click on Add an Application ID URI and select a scope name such as UserScope.All). That URI can form the scope name; the text ./default appended to it is used by Microsoft Azure, but other providers may have different requirements.

Once your application has sent the HTTP request, it will receive an IDP access token in JWT format. You can use the jwt.io website to examine it if you wish. The decoded output will reveal token issue and expiry times (they are in UNIX timestamp format; an online timestamp converter can be used to convert to a real time).

Now your application can proceed to send a request to the GBG identity solution at https://api.gbgplc.com and exchange that IDP access token for a GBG access token which is also in JWT format. The SDKs have a function to perform this step (see the Obtaining a GBG Access Token section in the SDK guides) alternatively a HTTP request can be sent (the Python demo code get_token.py file contains an example of this, or see the Get Started guides Postman example).

The client secret method provides for access to be revoked at any time, by deleting the secret from within the Azure portal. It is a far more secure solution than sending a username and password. Depending on how your application and solution is architected, the client secret may reside in a secure server belonging to your enterprise. Any application (a mobile app is shown in the example diagram below) may send a request for the secure server to obtain the IDP access token on its behalf. In this way, the client secret does not need to be stored or configured in the mobile app. The mobile app uses the temporary IDP access token to get the GBG access token. Both tokens eventually expire (often after an hour) as described above.

 

M2M using Certificates

If you wish to use a certificate instead of a client secret, then the general procedure is to generate a private key on a PC or server, and use it to create a public certificate that can be uploaded to the delegated authentication identity provider’s portal (with Microsoft Azure the PEM format can be used). The steps here are provided as a convenience, it is provider dependent and it is advisable to check the documentation for the provider that you are using. The steps use Microsoft Azure as the example provider. This example uses OpenSSL as the tool for key and certificate creation (if you're using a Linux machine it may already be pre-installed). The precise procedures will depend on the provider and the tools you choose to use. For background reading material, the following Medium article is very useful: OAuth 2.0 Client Authentication article.

Ensure you have a working installation of OpenSSL on a computer (Linux was used in this example) and issue the following command:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

The OpenSSL software will prompt you for certain information. Here is an example session:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
Generating a RSA private key
............................++++
..........................................++++
writing new private key to 'key.pem'
Enter PEM pass phrase: <enter any secret password here and remember it>
Verifying - Enter PEM pass phrase:
----- <re-enter the secret password>
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:UK
State or Province Name (full name) [Some-State]:Slough
Locality Name (eg, city) []:Slough
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Central Services Online
Organizational Unit Name (eg, section) []:Sales Team
Common Name (e.g. server FQDN or YOUR name) []:Central Services Online
Email Address []: bob@mycentralservicesonline.com

The OpenSSL interaction will result in the following two files being generated:

key.pem : A text file containing a private key (see Public-key Cryptography). This file must be kept secured at all times. The content in the file is encrypted and requires the secret passphrase that was entered during the openssl interaction to decode it.

cert.pem : A text file containing a public certificate. The public certificate contains your organization details (as entered in the OpenSSL interaction above) along with a public key. You can view the information in the cert.pem file by pasting it into online PEM decoder tools if desired.

The private key is temporarily needed in an unencrypted format. Use the following command to generate a rsa.pem file from it.

openssl rsa -in key.pem -out rsa.pem

As with the key.pem file, the rsa.pem file must be kept secured at all times (the rsa.pem file can be deleted after use, since it can be regenerated at any time from the key.pem file, provided the secret passphrase is known).

Within the Azure portal click on Azure Active Directory -> App registrations, select the application and then click Certificates & Secrets -> Upload certificate and upload the public certificate file (cert.pem).


The Microsoft Azure OAuth service is now ready to accept HTTP requests containing content signed with your private key. The content needs to be in a specific format when using Azure. The steps to build the content now follow.

Click on Manifest and scroll down to the field keyCredentials. The block of values there will have been derived from the uploaded certificate. Make a note of the customKeyIdentifier value as shown highlighted below.


Convert the customKeyIdentifier content from hexadecimal to Base64. The Base64 Guru will help you.


Next, go to the jwt.io website and enter the following information in the Decoded fields.
This content is typed in the box labelled HEADER. The Base64 content is inserted as the x5t value:

{
  "alg": "RS256",
  "typ": "JWT",
  "x5t": "bapzWPXnPM3D4oFn7gdtCXXP4ng="
}

In the box labelled PAYLOAD type the following:

{
  "iss": "ccc1caab-aacc-3c3c-acaa-a11c11a11caa",
  "sub": "ccc1caab-aacc-3c3c-acaa-a11c11a11caa",
  "exp": 1582911241,
  "jti": "10004",
  "aud": "https://login.microsoftonline.com/0e32de63-4491-40ea-b9c9-4444a1b18877/oauth2/v2.0/token"
}


The fields are described here:
iss : This field contains the Application (client) ID which can be obtained from the Azure portal.

sub : This field also contains the Application (client) ID.

exp : This field contains a UNIX timestamp. To obtain this, go to an online UNIX Timestamp tool and add (as an example) 3600 to the current timestamp.

jti : This field contains any unique number. It is used to ensure that the same content is not replayed within the time specified in the exp field above.

aud: This field contains a URL that can be obtained from within the Azure portal by clicking on Azure Active Directory -> App Registrations, and then clicking on Endpoints as shown below. From the list of URLs that will be displayed, you will require the URL listed under OAuth 2.0 token endpoint (v2)

The VERIFY SIGNATURE section of the jwt.io web page will contain two boxes. One will be labelled Public Key or Certificate and it can be ignored. The second box will be labelled Private Key. Paste the entire content of your rsa.pem file inside that box (the content will not leave the browser provided the third party jwt.io webpage can be trusted). After you have done that, the left side of the page (the box marked Encoded) will contain a token in JWT format. Copy the entire token. This token is effectively specific content (as entered in the boxes such as the one labelled PAYLOAD) that is signed with your private key. Your public key (as uploaded to the Azure portal in the cert.pem file) can be used by Azure to decrypt it.

The screenshot below shows what the jwt.io page will look like at this stage. The content in the Encoded box needs to be copied in its entirety.

Now the HTTP request can be built. It is similar to the earlier M2M using Pre-shared Client Secret method, with some differences. The fields are described here:

HTTP POST URL: This is the same as described in the pre-shared client secret method

grant_type: This is the same as before too. It must be set to the text client_credentials

client_id: This is same as before too. It is the Application (client) ID, as described above.

scope: This again is the same. It is the Application ID URI, (ending in /.default in the case of Microsoft Azure) as described above

client_assertion_type: This field is set to the text urn:ietf:params:oauth:client-assertion-type:jwt-bearer

client_assertion: This field is set to the JWT formatted token content, taken from the Encoded field output from the jwt.io webpage.

Once your application has sent the HTTP request, it will receive an IDP access token in JWT format as with the client secret method described earlier.

You’re now all set to proceed with sending the IDP access token to the GBG server to obtain the GBG access token.