Authentication and Authorization guide

Introduction

Cisco DNA Center has a REST API that an authenticated and authorized user can leverage to do operations over an HTTPS connection.

When the user autenticates, it receives a token that it needs to send in the following requests in order to be authorized to execute calls to the API.

Goal

The goal of this guide is create a script that authenticates against the Cisco DNA Center API and obtains the authorization token needed to make requests to the API.

Authentication workflow

Endpoints and methods used

  • POST /dna/system/api/v1/auth/token

Prerequisites

For this module, it is recommended that the user has general python and REST APIs knowledge. The following links can help you get up to speed if needed:

Environment

This guide was developed using:

Authentication API

The Authentication endpoint used in this guide is /dna/system/api/v1/auth/token, which is valid for version 1.2.6 and above. The HTTP method used for the endpoint is POST and it requires for the user to send its credentials using Basic Authentication.

Note: For systems with versions below that, the endpoint is /api/system/v1/auth/token

Basic Authentication

Authentication is done by using the Basic authentication scheme, as defined in RFC 7617.

The format of the credentials is USERNAME:PASSWORD and it needs to be base64 encoded. Then, the encoded string is sent as part of the Authorization header over clear text, hence doing it over a HTTPS/TLS connection is highly recommended.

AES Key Encryption

Cisco DNA Center support is extended for AES key encryption for token APIs, which is an optional feature that computes and formats the authorization header of token APIs in a base 64 encoded string of 256-bit AES key.

The format of the string is CSCO-AES-256 credentials=Base64Encode(AESEncrypt(username:password , aes256 key)).

The AESEncrypt first encrypts the username:password pair with a 256 bits AES key and then Base64Encode encodes the result in base 64 string format.

Authorization is done by AES256 scheme, as defined in RFC 2617.

Note:

  • You can enable the AES key encryption from Cisco DNA Center system configuration.
  • If you disable the AES key encryption from the Cisco DNA Center system configuration, the default basic authentication is enabled by default.

Token

Once the user authenticates, it receives a token from the API endpoint, which needs to be included in every request as part of the X-Auth-Token header.

Authentication code

We will create a python script that authenticates and prints the token that is needed for authentication.

We will use the python requests library, importing both the requests library but also the HTTPBasicAuth specifically, which simplifies the Basic Authentication process.

import requests
from requests.auth import HTTPBasicAuth

Next, we will import the urllib3 library and call the disable_warnings() function. This is NOT recommended on a production environment. We use it here in the development environment to avoid the warning that we would get of using a self-signed certificate in Cisco DNA Center.

import urllib3
urllib3.disable_warnings()

Next, we define four general variables of the script:

  • Base URL: IP Address or Fully Qualified Domain Name (FQDN) of the Cisco DNA Center server
  • Auth URL: API endpoint used for authentication
  • Username: Cisco DNA Center USERNAME
  • Password: Cisco DNA Center PASSWORD
BASE_URL = 'https://10.10.10.181'
AUTH_URL = '/dna/system/api/v1/auth/token'
USERNAME = '<USERNAME>'
PASSWORD = '<PASSWORD>'

Finally, the request is done using POST, which returns a json body with the token. The verify=False parameter is used in order to query a server with a self-signed certificate. On a production environment, with a valid certificate generated by a trusted certificate authority, it is not needed.

response = requests.post(baseUrl + authUrl, auth=HTTPBasicAuth(USERNAME, PASSWORD), verify=False)
print(response.json()['Token'])

Code

The repository for this guide is here. The complete code is shown below:

# Module import
import requests
from requests.auth import HTTPBasicAuth

# Disable SSL warnings. Not needed in production environments with valid certificates
import urllib3
urllib3.disable_warnings()

# Authentication
BASE_URL = 'https://<IP Address>'
AUTH_URL = '/dna/system/api/v1/auth/token'
USERNAME = '<USERNAME>'
PASSWORD = '<PASSWORD>'

response = requests.post(BASE_URL + AUTH_URL, auth=HTTPBasicAuth(USERNAME, PASSWORD), verify=False)
print(response.json()['Token'])