Flujo de datos OAuth

La aplicación tiene que obtener un token de acceso antes de utilizar cualquier API en Cytomic Orion. Para ello es necesario intercambiar cierta información con el servidor CAS.

Protocolo utilizado en el intercambio de datos

OAuth utiliza el protocolo HTTPS para intercambiar flujos de información entre la aplicación y el servidor CAS para conseguir la autorización sobre las APIs de Cytomic Orion. En este intercambio de datos se utiliza el comando POST del protocolo HTTP. Por razones de seguridad todos los comandos enviados y las respuestas obtenidas viajan cifrados mediante HTTPS.

Tipo de acceso soportado por el servidor CAS y datos requeridos

El protocolo OAuth soporta varios tipos autenticación y autorización dependiendo de las características de la aplicación desarrollada que accederá a la API de Cytomic Orion. En el caso particular de Cytomic Orion, el tipo de acceso permitido por el servidor CAS será “password”, que deberá ser indicado en el parámetro “grant_type” de la petición inicial de la aplicación.

Con el grant_type password, el servidor CAS requiere los siguientes datos para permitir el acceso a la API de Cytomic Orion para una aplicación registrada:

Flujos de información generados para autorizar un acceso

El esquema de comunicación en la fase de autenticación entre la aplicación y el servidor CAS es el siguiente:

Esquema de comunicación OAuth entre una aplicación y el servidor CAS

En la figura se muestra un intercambio de datos OAuth completo:

  • La aplicación envía sus credenciales y las del cliente al servidor CAS. El servidor CAS valida las credenciales de la aplicación en el servidor IdP y si es correcto comprueba las credenciales del cliente para generar y emitir un token de acceso y un token de refresco.

  • Con el token de acceso la aplicación accede a la API de Cytomic Orion y recupera los datos requeridos.

  • Una vez que el token de acceso caduca el servidor CAS lo rechaza. La aplicación envía el token de refresco para recuperar un nuevo token de acceso y de refresco.

Autenticación, autorización y obtención del token de acceso

Petición del token de autorización por parte de la aplicación

La aplicación envía un comando HTTPS POST al servidor CAS https://auth.pandasecurity.com con los parámetros siguientes:

POST /oauth/token HTTP/1.1

Host: auth.pandasecurity.com

Content-Type: application/x-www-form-urlencoded; charset=utf-8

grant_type =password

&client_id ={CLIENT_ID}

&client_secret = {CLIENT_SECRET}

&username = {USER_NAME}

&password = {USER_PASSWORD}

&scope ={SCOPE}

Alternativamente se puede utilizar una cabecera de tipo Authorization para indicar el client_id y client_secret codificado como base64:

POST /oauth/token HTTP/1.1

Host: auth.pandasecurity.com

Content-Type: application/x-www-form-urlencoded; charset=utf-8

Authorization: Basic client_id:client_secret.

 

grant_type=password

&username={USER_NAME}

&password={USER_PASSWORD}

&scope={SCOPE}

El significado de los parámetros es el siguiente:

Parámetro Descripción

grant_type

Requerido. Establece el valor a “password”. Indica que la aplicación será la que proveerá directamente las credenciales de la cuenta de la aplicación al que pertenece el recurso protegido.

client_id

Requerido. Es el identificador del cliente de Cytomic Orion al que pertenece la aplicación.

client_secret

Requerido. Es la contraseña del cliente de Cytomic Orion al que pertenece la aplicación.

username

Requerido. El nombre de la cuenta de la aplicación creada en la consola de Cytomic Orion. Consulta Habilitar el acceso a la API desde programas externos

password

Requerido. La contraseña de la cuenta de la aplicación creada en la consola de Cytomic Orion. Consulta Habilitar el acceso a la API desde programas externos

scope

Ámbito del acceso. Establece el valor a “orion.api”.

Parámetros requeridos por el servidor CAS para obtener el token de acceso

Respuesta correcta del servidor CAS

La respuesta es un objeto JSON con el token de acceso y otros datos:

HTTP/1.1 200

{

"access_token":"{ACCESS_TOKEN}",

"refresh_token":"{REFRESH_TOKEN}",

"expires_in":{EXPIRATION_TIME},

"token_type":{TOKEN_TYPE}

}

El significado de los campos es el siguiente:

Campo Descripción

access_token

Token de acceso compuesto por una cadena de caracteres codificada en base64.

refresh_token

Token de refresco compuesto por una cadena de caracteres codificada en base64.

expiration_time

Tiempo en segundos que durará el token de acceso.

token_type

Por defecto “bearer”. Indica que se trata de un token autocontenido y que por tanto contiene todos los recursos necesarios para autorizar el acceso. El servidor CAS emite tokens de acceso JWT (Json Web Token) firmados.

Respuesta del servidor CAS con el token de acceso y de refresco

Respuesta errónea del servidor CAS

El servidor no ha conseguido generar un token válido con la información suministrada:

HTTP/1.1 400 Bad request

{

"error":"{ERROR_CODE}",

"error_description":"{ERROR_DESC}"

"error_uri":"{ERROR_URI}"

}

El significado de los campos es el siguiente:

Campo Descripción

error

Código de error: consulta la tabla Códigos de retorno.

error_description

Descripción breve del error. El contenido de este campo no está preparado para ser mostrado directamente al usuario de la aplicación. En su lugar, se deberán adecuar las descripciones de los mensajes en función de la aplicación.

error_uri

Opcional.

Respuesta errónea del servidor CAS

Refresco de un token de acceso caducado

Debido a que el ámbito de acceso de una aplicación puede cambiar a lo largo del tiempo, el token de acceso que utiliza para acceder a la API de Cytomic Orion tiene una caducidad de 20 minutos, transcurridos los cuales la API de Cytomic Orion lo rechazará impidiendo el acceso al recurso. Para evitar el envío de los parámetros indicados en Autenticación, autorización y obtención del token de acceso cada vez que el token de acceso caduca, la aplicación envía al servidor CAS el token de refresco. De esta manera, el token de refresco es una referencia a las condiciones originales que propiciaron la autorización de la aplicación en el servidor CAS; si éstas condiciones no han variado, el servidor CAS volverá a enviar un token de acceso a la aplicación. El token de refresco tiene un tiempo de vida superior al token de acceso.

Envío del token de refresco

La aplicación envía al servidor CAS auth.pandasecurity.com un comando HTTPS POST con los parámetros siguientes:

POST /oauth/token HTTP/1.1

Host: auth.pandasecurity.com

Content-Type: application/x-www-form-urlencoded; charset=utf-8

 

grant_type = refresh_token

&refresh_token = {REFRESH_TOKEN}

&client_id = {CLIENT_ID}

&client_secret = {CLIENT_SECRET}

&scope = {ORIGINAL_SCOPE}

El significado de los parámetros es el siguiente:

Parámetro Descripción

grant_type

Requerido. Establece el valor a refresh_token para indicar que la aplicación envía un token de refresco esperando a cambio del CAS un nuevo token de acceso.

refresh_token

Token de refresco necesario para que el servidor CAS genere un nuevo token de acceso.

client_id

Requerido. Es el identificador del cliente de Cytomic Orion.

client_secret

Requerido. Es la contraseña del cliente de Cytomic Orion.

scope

Opcional. Si no se incluye, el servidor CAS devolverá un token de acceso con el mismo ámbito que la petición original. Si se incluye deberá contener el mismo ámbito que la petición original.

Parámetros requeridos por el servidor CAS para obtener un nuevo token de acceso

Respuesta correcta del servidor CAS

La respuesta del servidor CAS a la aplicación es la misma que se generó en la petición original por el token de acceso. El servidor CAS puede incluir un nuevo token de refresco que será utilizado en la siguiente renovación del token de acceso. Si el servidor CAS no incluye un nuevo token de refresco se asume que el anterior sigue siendo válido.

Respuesta errónea del servidor CAS

El servidor no ha conseguido generar un token válido con la información suministrada:

HTTP/1.1 400 Bad request

{

"error":"invalid_request"

}

Códigos de error

Código Descripción

200

Operación completada con éxito.

400

Error.

Códigos de retorno

Mensajes de error

Código de error Descripción

unrecognized_client_id

El identificador del cliente es erróneo o no existe. Contacta con el departamento de soporte de Cytomic.

unrecognized_client_secret

La contraseña del cliente es errónea o no se corresponde con el client_id enviado. Contacta con el departamento de soporte de Cytomic.

unauthorized_client

El cliente está autenticado pero no está autorizado para hacer la petición.

invalid_client

Cualquier otro error relativo a la validación de las credenciales del cliente. Contacta con el departamento de soporte de Cytomic.

unsupported_grant_type

El grant_type enviado no está soportado. Utiliza “password”.

invalid_grant

El token de acceso recibido no es válido (no se reconoce o ha caducado) o la aplicación no tiene autorización para acceder a la API.

invalid_scope

El scope recibido no es correcto. Este parámetro siempre debe ser “orion.api”.

access_denied

Usuario o contraseña erróneos.

invalid_request

La petición contiene un parámetro incompatible o no contiene todos los parámetros requeridos.

temporarily_unavailable

El servidor CAS no puede procesar la petición debido a una sobrecarga temporal o a un proceso de mantenimiento.

server_error

Error interno del servidor.

Mensajes de error en el proceso de autorización

Ejemplo para obtener un token de acceso y de refresco del servidor CAS

El ejemplo mostrado a continuación construye la llamada al servidor CAS con los parámetros username, password, client_id, client_secret, grand_type y scope apropiados para recuperar el token de acceso y el token de refresco necesarios para posteriores llamaras a la API de Cytomic Orion.

#utiliza la librería requests para conectar con el servidor OAuth

import requests

from requests.auth import HTTPBasicAuth

#establece el client_id, client_secret, username, password y scope

client_id = 'aaf1461b7a8a593199665'

client_secret = 'YaDzUdHmlrivXYaAFhJDFiNe5x0mI4'

username = '7e0aa013282249cdebd15a08f84d'

password = 'jEshWDjjS2h6bCxrZKCy8iVbBHNcCzMxxUe362CfUwz0eAKXRdlz9uOuVzFp3g'

grant_type = 'password'

token_url = 'https://auth.pandasecurity.com/oauth/token'

scope = 'orion.api'

headers = {

'Content-Type': 'application/x-www-form-urlencoded',

}

#configura el cuerpo del mensaje HTTP. Las credenciales del client_id y

#client_secrent se establecen en las cabeceras del mensaje

body = {

'username': username,

'password': password,

'scope': scope,

'grant_type': 'password'

}

#codifica el client_id y client_password en base64 y lanza la petición HTTPS

r = requests.post(token_url, auth=HTTPBasicAuth(client_id, client_secret),

headers=headers, data=body, verify=False)

#si no hay errores convierte el cuerpo de la respuesta en un JSON para facilitar #el acceso

if r.status_code==200:

data = r.json()

#carga el token de acceso y de refresco en las variables

token_access=data['access_token']

token_refresh=data['refresh_token']

Ejemplo de uso del token de acceso y token de refresco

Todas las llamadas a la API de Cytomic Orion deben de incorporar en las cabeceras HTTP el token de acceso obtenido tras el proceso de autenticación y autorización. Sin embargo, transcurridos 20 minutos de la emisión del token de acceso, éste caduca y es necesario obtener uno nuevo a través del token de refresco. Por esta razón, es necesario comprobar en cada llamada a la API de Cytomic Orion que no devuelve un error de token inválido. Si éste es el caso solicita un nuevo token de acceso y reintenta la petición con el nuevo token.

#llamada de ejemplo a la API de indicios

#establece los parámetros necesarios

alert_from='1572595090000' #desde 1/11/2019

alert_to='1575187090000' #hasta 1/12/2019

 

#prepara la cabecera HTTP con el token de acceso para lanzar la llamada a la API

h_request = {

'Authorization': f'Bearer {token_access}',

'Accept': 'application/json'

}

 

url_alert = f'https://api.orion.cytomic.ai/api/v1/applications/alerts/{alert_from}/{alert_to}'

r = requests.get(url_alert, headers=h_request, verify=False)

#una vez autenticado comprueba en cada llamada si el token de acceso caducó

if r.status_code==401:

body_refresh = {

'grant_type':'refresh_token',

'refresh_token':token_refresh,

'client_id':client_id,

'client_secret':client_secret,

}

#pide un nuevo token de acceso y refresco

r = requests.post(token_url, headers=headers, data=body_refresh,verify=False)

data = r.json()

#actualiza las variables con el nuevo token de acceso y refresco

token_access=data['access_token']

token_refresh=data['refresh_token']