Authentication Walkthrough
  • 06 Aug 2024
  • 3 Minutes to read
  • Contributors
  • Dark
    Light

Authentication Walkthrough

  • Dark
    Light

Article summary

The examples provided below will assist you in verifying the correct implementation of the RealTheory Authorization header.

When reviewing the example, consider the following hypothetical security credentials for your RealTheory account:

  • Domain: acme
  • Username: APIKey1
  • Secret: 41698726-5B09-4F24-BDE2-FF0A91CA426F

1. Example - GET Request

Consider the following GET request:

GET https://myendpoint.realtheory.io/theory/api/v1/k8scost/namespacecosts/{53214960-fda3-4089-9e12-a7f476317352}/daily/usd?offset=7d&span=7d

The complete HTTP request also includes these HTTP headers:

"Accept": "application/json"
"TimeStamp": "2024-03-13T13:40:31.988Z"

In order to calculate the authorization header, we must first calculate the canonical resource. This refers to the URL path encoded version of the absolute path portion of a request URI, starting with the “/” that follows the domain name and up to the end of the string or to the question mark character (‘?’) if you have query string parameters. If the absolute path is empty, use a forward slash character (/)

In the above example, the canonical resource is:

/theory/api/v1/k8scost/namespacecosts/%7B53214960-fda3-4089-9e12-a7f476317352%7D/daily/usd

Note: { and } characters are encoded to %7B and %7D in the example above.

Next, we calculate the string to sign. This can be generated using the following pseudo grammar:

StringToSign = HTTP-Verb + "\n" +
	Content-MD5 + "\n" +
	Content-Type + "\n" +
	TimeStamp + "\n" +
	CanonicalizedResource;

For the above example, the string to sign is:

GET\n\n\n2024-03-13T13:40:31.988Z\n/theory/api/v1/k8scost/namespacecosts/%7B53214960-fda3-4089-9e12-a7f476317352%7D/daily/usd

Note: As Content-MD5 or Content-Type are meaningless and not present for GET requests, these values were substituted with an empty string ("") when calculating the string to sign.

Next, we calculate the HMAC signature. This can be generated using the following pseudo grammar:

HMAC = RTv1-SHA256-Signature

Signature = Base64( HMAC-SHA256( UTF-8-Encoding-of( YourAPIKey ), UTF-8-Encoding-Of ( StringToSign ) ) );

For the above example, the signature is calculated as:

bAcoIce1w06fxl34V6WNpcoBKDzqd4VXvy6FXpnfFgY=

When adding the signature marker and version, the full HMAC signature is:

RTv1-SHA256-bAcoIce1w06fxl34V6WNpcoBKDzqd4VXvy6FXpnfFgY=

Next, we build the full authorization header value. The authorization header value takes the following format:

{domain}\{username}:{secret}\{HMAC}

So for the above example, prior to Base64 encoding, the authorization header value is:

acme\APIKey1:41698726-5B09-4F24-BDE2-FF0A91CA426F\RTv1-SHA256-bAcoIce1w06fxl34V6WNpcoBKDzqd4VXvy6FXpnfFgY=

After Base64 encoding the authorization header value, the full header, with key is:

"Authorization": "Basic YWNtZVxBUElLZXkxOjQxNjk4NzI2LTVCMDktNEYyNC1CREUyLUZGMEE5MUNBNDI2RlxSVHYxLVNIQTI1Ni1iQWNvSWNlMXcwNmZ4bDM0VjZXTnBjb0JLRHpxZDRWWHZ5NkZYcG5mRmdZPQ=="

2. Example - POST Request

Consider the following POST request:

POST https://myendpoint.realtheory.io/theory/api/v1/configuration/userconfigurations

The complete HTTP request includes the following request body:

{"settings":{"key1":"value1","key2":"value2"}}

and corresponding HTTP headers:

"Accept": "application/json"
"TimeStamp": "2024-03-13T13:40:31.988Z"
"Content-MD5": "S9gM/YZIOK0M0PpHzgvFMQ=="
"Content-Length": "48"
"Content-Type": "application/json"

In order to calculate the authorization header, we must first populate the Content-MD5 and Content-Length HTTP headers within the HTTP request. To calculate the Content-MD5 header, simply calculate the MD5 checksum of the request body and base64 encode the result.

For the request body above, the corresponding Content-MD5 and Content-Length HTTP headers should be:

"Content-MD5": "S9gM/YZIOK0M0PpHzgvFMQ=="
"Content-Length": "48"

Next we must calculate the canonical resource. This refers to the URL path encoded version of the absolute path portion of a request URI, starting with the “/” that follows the domain name and up to the end of the string or to the question mark character (‘?’) if you have query string parameters. If the absolute path is empty, use a forward slash character (/)

In the above example, the canonical resource is:

/theory/api/v1/configuration/userconfigurations

Next, we calculate the string to sign. This can be generated using the following pseudo grammar:

StringToSign = HTTP-Verb + "\n" +
	Content-MD5 + "\n" +
	Content-Type + "\n" +
	TimeStamp + "\n" +
	CanonicalizedResource;

For the above example, the string to sign is:

POST\nS9gM/YZIOK0M0PpHzgvFMQ==\napplication/json\n2024-03-13T13:40:31.988Z\n/theory/api/v1/configuration/userconfigurations

Next, we calculate the HMAC signature. This can be generated using the following pseudo grammar:

HMAC = RTv1-SHA256-Signature

Signature = Base64( HMAC-SHA256( UTF-8-Encoding-of( YourAPIKey ), UTF-8-Encoding-Of ( StringToSign ) ) );

For the above example, the signature is calculated as:

Woggmyo60xTEauex6cEEIhp4tA/0rdXpkp7zagPOuLg=

When adding the signature marker and version, the full HMAC signature is:

RTv1-SHA256-Woggmyo60xTEauex6cEEIhp4tA/0rdXpkp7zagPOuLg=

Next, we build the full authorization header value. The authorization header value takes the following format:

{domain}\{username}:{secret}\{HMAC}

So for the above example, prior to Base64 encoding, the authorization header value is:

acme\APIKey1:41698726-5B09-4F24-BDE2-FF0A91CA426F\RTv1-SHA256-Woggmyo60xTEauex6cEEIhp4tA/0rdXpkp7zagPOuLg=

After Base64 encoding the authorization header value, the full header, with key is:

"Authorization": "Basic YWNtZVxBUElLZXkxOjQxNjk4NzI2LTVCMDktNEYyNC1CREUyLUZGMEE5MUNBNDI2RlxSVHYxLVNIQTI1Ni1Xb2dnbXlvNjB4VEVhdWV4NmNFRUlocDR0QS8wcmRYcGtwN3phZ1BPdUxnPQ=="

Was this article helpful?

What's Next