OAuth 2.0: flujos para obtener un token de acceso
OAuth 2.0[1] es un protocolo de autorización de estándar abierto que permite a terceros (aplicaciones) acceder a los datos de un usuario sin que el usuario tenga que informar sus credenciales. Apps usan este método para obtener acceso a la cuenta de un usuario determinado a través de un client ID o client secret (claves de autenticación de OAuth).
Si desea obtener más información, visite este sitio web: http://oauth.net/2/. |
Tipos de clientes
En OAuth, hay dos tipos de clientes:
-
Cliente confidencial: se trata de clientes que pueden garantizar que ningún usuario malintencionado obtendrá un client secret o client ID para intentar pasar por una aplicación válida.
-
Cliente no confidencial: clientes que no pueden garantizar que un usuario malintencionado obtendrá su client secret o client ID para intentar pasar por una aplicación válida. En estos casos, se informa una dirección URL de devolución de llamada para asegurarse de que la información vuelve solo a la aplicación original. Como alternativa, el tiempo de vida del client ID se puede reducir mediante un refresh token.
Formas de obtener un access token
Hay diferentes flujos de OAuth 2.0, que exigen formas distintas de obtener un token de acceso.
Para algunos métodos, debe enviar un extraInfo .
Los valores enviados como extraInfo se muestran en el campo Extra Fields de la pantalla de información general de un token, a la que se puede acceder haciendo clic en el nombre de un token en la página Access Tokens.
|
Authorization Code
1. Generación de un authorization code:
En primer lugar, se debe haber creado una aplicación.
Con ella, podemos obtener el client ID, que es el primer elemento que debemos informar a través de una petición POST a este endpoint: <gateway URL>/oauth/grant-code
.
El header debe contener la siguiente información:
Content-Type: application/json
Tenemos que incluir los siguientes elementos en el cuerpo:
{
"client_id": "f9212173-e705-373b-a698-61923e378359",
"extraInfo": {},
"redirect_uri": "string",
"state": "string"
}
El client ID informado debe ser el mismo de la app creada. |
Una vez hecho esto, se espera una respuesta que contenga un authorization code, como en el ejemplo siguiente:
{
"redirect_uri": "string?state=string&code=8748d39f-1d4f-311f-92c6-4b279db1b317"
}
2. Notificación del authorization code para generar el access token:
Debe realizar una nueva petición POST, a este endpoint: <gateway URL>/oauth/access-token
.
El header debe contener la siguiente información:
Authorization: Basic client_id:client_secret
En el cuerpo, debemos informar el código de autorización generado por el endpoint anterior y el grant type en el formato x-www-form-urlencoded
, como en este ejemplo:
grant_type=authorization_code&code=8748d39f-1d4f-311f-92c6-4b279db1b317
Por último, se generará el token de acceso y se devolverá el siguiente código:
{
"access_token": "57f10f0e-3d2e-311f-a797-4011f66e1cbf",
"refresh_token": "ca81cb16-43e4-3e96-aaea-4861e7791dc7",
"token_type": "access_token",
"expires_in": 3600
}
Refresh Token
El refresh token se usará para actualizar un access token caducado. Para actualizar un token, siga los pasos que se indican a continuación.
En primer lugar, realice una petición POST a este endpoint: <gateway URL>/oauth/access-token
.
El header debe contener la siguiente información:
Authorization: Basic client_id:client_secret
En el cuerpo, debemos incluir el refresh_token
recibido desde el endpoint anterior (que generó el access token) y el grant type en el formato x-www-form-urlencoded
, como en este ejemplo:
grant_type=refresh_token&refresh_token=ca81cb16-43e4-3e96-aaea-4861e7791dc7
Por último, se regenerará el access token y se devolverá un código como el ejemplo siguiente.
{
"access_token": "ca81cb16-43e4-3e96-aaea-4861e7791dc7",
"refresh_token": "677b881a-d0b6-3b29-b9a8-f0cdb50ce035",
"token_type": "access_token",
"expires_in": 3600
}
Implicit
El flujo Implicit se utiliza para obtener tokens de acceso para clientes públicos de forma optimizada. Puede funcionar a través de una IRO de enrutamiento privado junto con un access token. Estos clientes se implementan normalmente en un navegador mediante un lenguaje de script, como JavaScript.
Al igual que con OAuth 2.0 Authorization Code, se debe haber creado una app para que podamos tener acceso al client ID.
Después de eso, realice una petición POST a este endpoint: <gateway URL>/oauth/access-token
.
Debe contener el siguiente header:
Content-Type: application/json
Debemos incluir estos elementos en el cuerpo:
{
"grant_type": "implicit",
"redirect_uri": "<URL>",
"client_id": "<client ID>"
}
El client ID debe ser el mismo de la app creada. |
Tenga en cuenta que la aplicación debe contener un extra field denominado redirect_uri , con una dirección URL válida como valor, que debe ser informado al solicitar el token (por ejemplo: http://supermock.demo.sensedia.com/ ).
Acceda a esta página para ver más información sobre cómo crear y configurar apps, agregando extra fields.
|
Cuando se realiza el proceso, se espera una respuesta que contenga el URI y el token de acceso, como el ejemplo siguiente.
{
"redirect_uri": "www.url.com?access_token=57f10f0e-3d2e-311f-a797-4011f66e1cbf",
"expires_in": 3600
}
Client Credentials
Al igual que el flujo Implicit, Client Credentials NO genera un refresh_token
.
Por lo tanto, no es posible actualizar un token de acceso cuando expira.
Cuando se usa este flujo, al crear un nuevo access token, debe informar el nombre de la app y el client ID en el campo Extra Info
del token, informando también de todos los valores de los campos adicionales (extra fields) que están registrados para esa app.
Acceda a esta página para ver más información sobre la creación y configuración de apps, agregando campos adicionales.
Se debe haber creado una app para que podamos obtener el client ID y el client secret.
A continuación, es necesario realizar una petición POST a este endpoint: <gateway URL>/oauth/access-token
.
La petición debe contener el siguiente header:
Authorization: Basic client_id:client_secret
En el cuerpo, debemos informar el grant_type
en formato x-www-form-urlencoded
:
grant_type=client_credentials
A continuación, se generará el access token y se debe devolver como en el ejemplo siguiente.
{
"access_token": "6c164a82-84a6-3bc4-8122-f777121a4f62",
"token_type": "access_token",
"expires_in": 3600
}
También puede crear nuevos campos adicionales (extra fields) al generar el token de acceso. Para eso, es necesario añadir el siguiente header:
Content-Type: application/json
En el cuerpo, debemos informar el grant_type
y los campos adicionales, como en este ejemplo:
{
"grant_type": "client_credentials",
"extraInfo": {"value": "32423", "value2": "874yhgt3"}
}
Password
Se debe haber creado una app para que podamos tener acceso al client ID y el client secret.
Después de eso, debe realizar una petición POST a este endpoint: <gateway URL>/oauth/access-token
.
El header debe contener esta información:
Authorization: Basic client_id:client_secret
Además del grant_type
, el cuerpo debe contener otras dos piezas de información que utilizan el userDirectory
.
Son el login y la contraseña del usuario, que pueden ser de un LDAP o un REST, y deben estar en el formato x-www-form-urlencoded
:
grant_type=password&username=<login de usuario>&password=<contraseña>
Si el usuario y la contraseña son válidos en LDAP o REST, la devolución del access token debe ser similar al ejemplo siguiente:
{
"access_token": "6c164a82-84a6-3bc4-8122-f777121a4f62",
"token_type": "refresh_token",
"expires_in": 3600
}
Para que las características anteriores se apliquen a la app, debe configurar una API Identity. |
En el caso de LDAP, se debe informar el usuario en el formato User-Principal-Name (por ejemplo, test@da.sa ).
|
La propiedad oauth.grantTypes.resourceOwnerPassword.userDirectory ya no es necesaria.
|
JWT
"JSON Web Token (JWT) es un estándar abierto (RFC 7519) que define una forma compacta e independiente de transmitir información de forma segura entre partes como un objeto JSON. Esta información se puede verificar y confiar porque está firmada digitalmente. Los JWT se pueden firmar usando un secreto (con el algoritmo HMAC) o un par de claves pública/privada usando RSA." (https://jwt.io/)
En el flujo JWT, se debe haber creado una app para que podamos tener acceso al identificador de cliente y al secreto de cliente.
A continuación, debe realizar una petición POST a este endpoint: <gateway URL>/oauth/access-token
.
El header debe contener la siguiente información:
Authorization: Basic client_id:client_secret
En el cuerpo, debemos informar el code
generado por el endpoint de grant-code
y el grant type en el formato x-www-form-urlencoded
, como en este ejemplo:
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&code=8748d39f-1d4f-311f-92c6-4b279db1b317
El access token se generará de nuevo y se debe devolver como en el ejemplo siguiente.
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsb2NhbGhvc3QiLCJpc3MiOiIxNzIuMTguMC4xIiwic3ViIjoiOWI1Zjc3MWUtNzgyZC0zNTEwLWI2YmEtMzZlOWM2NWJmZDVkIiwiZXhwIjozNjAwLCJpYXQiOjE1Mjg5MTg2MzcsIkFwcDogIjoiUmljYXJkb0FwcCIsIkNvZGU6ICI6IjRlNWIyMTEzLTJkYzYtM2RlNi1iN2ZkLWNkOTYxOTMxZWQyOSIsImxvZ2luIjoidXNlci5sb2dpbiJ9.bhvFpiZ6em9tUgpHxGQGuH7cmvMy4I7STJDRBUybuPM",
"token_type": "access_token",
"expires_in": 3600
}
Con el código generado, deberá agregar el interceptor JWT al flujo de API. Él será responsable de validar el token. Ver más sobre este interceptor aquí.
Revocación de access token y refresh token
La revocación hace inutilizable un token que sigue siendo válido pero que ya no es necesario. Después de la revocación, el token no se acepta en peticiones a las APIs.
Se puede utilizar el endpoint /revoke
de la API «OAuth 2.0» para revocar un access token o un refresh token.
En ambos casos, se revocan todos los tokens — es decir, si se revoca un access token y hay un refresh token asociado a él, también se revoca, y si se revoca un refresh token, también se revoca el access token asociado a él.
Para hacer la revocación, hay que enviar una petición POST a <URL del gateway>/oauth/revoke
.
La petición debe contener el header Authorization
:
Authorization : Basic client_id:client_secret
En el cuerpo, pase la siguiente información en formato x-www-form-urlencoded
:
token=<valor>&token_type_hint=access_token
O
token=<valor>&token_type_hint=refresh_token
Tenga en cuenta que no es necesario pasar el token_type_hint
(porque el token se encuentra por el valor introducido), pero hace que la operación de revocación sea más rápida.
Share your suggestions with us!
Click here and then [+ Submit idea]