Authenticating API requests

To make API calls, Blue Planet uses a REST API client. The REST API client has two methods to authenticate API requests:

  1. HMAC signed requests—​Recommended authentication method for production use. See HMAC signed requests.

  2. Token authentication—​User-based authentication using a short-lived token without message signing. See Token authentication.

HMAC signed requests

For secure operation in a production environment, ensure REST clients of Blue Planet Orchestrate authenticate by signing the API request header with a Hashed Message Authentication Code (HMAC) and include the HMAC in the Authorization header of the request. To sign the API request, create an API key identifier and key secret pair. Your Blue Planet administrator must add a special key to each user profile in order to allow access to the API. See Creating user SSH keys for git access (optional).

An HTTP request defines an HTTP header value for the Authorization header. The value is a single string value that must start with the string "MAC" and then further encode the key ID, timestamp, nonce, and signature, in that order. The following table describes the authentication header values.

Table 1. Authentication header

Value

Identifier

Description

Example

Key Identifier

id

String identifying the key or secret. Does not change per call.

id="ae71d7d92d7d4c659a7d3336db6c4c99"

Timestamp

ts

Number of elapsed seconds from UNIX epoch. Changes per call.

ts="1411065195"

Nonce

nonce

A random number generated for session authentication that is only used once. This ensures that old communications cannot be reused in replay attacks. Changes per call.

nonce="@.L1H=HRL<W874G\\IQ W0Z09M>G24O;\\Q[I8X\\F?Q#GH"

MAC

mac

Signature. Changes per call.

mac="Nz4UIJLX//yR5V4ti0oQb3M37jY8lHdlmbN6wAEJ5Sk="

The following table shows an example of a full authorization header.

Table 2. Full authorization header example

Header

Value

Authorization

MAC id=ae71d7d92d7d4c659a7d3336db6c4c99,ts=1400863370,nonce="@.L1H=HRL<W874G\\IQ W0Z09M>G24O;\\Q[I8X\\F?Q#GH",mac="Nz4UIJLX//yR5V4ti0oQb3M37jY8lHdlmbN6wAEJ5Sk="

You must enclose any values in the header string that include non-HTTP tokens in quotes.

The signing algorithm is based on a variation of the OAuth standard signing algorithm (draft-ietf-oauth-v2-http-mac-02), section 3.2.1, with these exceptions:

  • Exclude the ext field.

  • Exclude the trailing new line character.

The signing algorithm constructs a canonical string built from the timestamp, nonce, HTTP method (upper case), URI path, host, and port. The signing algorithm is based on the header information only and requires no attention to the payload.

Additionally, the signing algorithm:

  • Uses the SHA-256 hashing algorithm to hash the canonical string.

  • Converts the hash value to ASCII using base64 coding, with the trailing new-line character ('\n') dropped.

  • Includes the MAC and the necessary parameters to verify the signature in the Authorization header.

See the Authorization Header table for details on how to construct the final header value.

The MAC is sufficient to authenticate the sender of the HTTP request using the keySecret; however, it is not sufficient to guarantee the payload has not been altered or to ensure privacy. For this reason, Ciena recommends secure HTTPS between the client and server.

Review the following Python reference implementation of the signing algorithm to understand the signing conventions:

sr = SignedRequest('GET', 'www.example.com', '/a/b/c?d=1&e=2&f=3', '443')
user = User.objects.get(id=1)
key_id = user.key_id
key = user.key
nonce = binascii.b2a_uu(os.urandom(32)).replace(' \n', '').replace('"', '')
timestamp = str(int(time.time()))
header, value = sr.get_signed_header(nonce, timestamp, key_id, key)
assert(sr.verify_signed_header(value, key))

Example rsign request:

>>> import rsign
>>> import requests
>>> sr = rsign.SignedRequest('GET', 'bp.example.com', '/test/api/v1/', '443')
>>> api_key_id = 'ae71d7d92d7d4c659a7d3336db6c4c99'
>>> api_key = '7888cef675c44e8f862bae75186140d7'
>>> timestamp = str(int(time.time()))
>>> nonce = binascii.b2a_uu(os.urandom(32)).replace(' \n', '').replace('"', '')
>>> header = sr.get_signed_header(nonce, timestamp, api_key_id, api_key)
>>> header
('Authorization', 'MAC id="ae71d7d92d7d4c659a7d3336db6c4c99", ts="1400863370", nonce="@.L1H=HRL<W874G\\IQ W0Z09M>G24O;\\Q[I8X\\F?Q#GH", mac="Nz4UIJLX//yR5V4ti0oQb3M37jY8lHdlmbN6wAEJ5Sk="')
>>> res = requests.get('https://bp.example.com/test/api/v1/' headers=dict((header,)))
>>> res
<Response [200]>

Token authentication

You can choose to exchange user login credentials (user name, password, and tenant name) for a short-lived token (24-hour default). The token is included in the Authorization HTTP header and grants the caller access appropriate for the corresponding user roles.

Obtain the token either by providing user credentials to the UAC (Tron) application directly (POST to /tron/api/v1/tokens).

The header value is in the format: Authorization: token <token_value>

where you replace the <token_value> in the request.

This method returns the token in the body or through the Blue Planet Orchestrate authentication component (POST /bpocore/authentication/api/v1/tokens). This method returns the token in the X-Subject-Token HTTP response header.

You can also use the Swagger UI to run the API call to the authentication component.

Ensure you review the Blue Planet MDSO and NFVO Solutions Release Notes for the latest details.

results matching ""

    No results matching ""