Implementando Authorization Code Grant (PKCE)
Clase 25 de 39 • Curso de Autenticación con OAuth
Contenido del curso
JSON Web Tokens
- 5

JSON Web Tokens
08:34 min - 6

Autenticación tradicional vs JWT
08:08 min - 7

Configuración inicial de los proyectos
08:22 min - 8

Firmando un JWT
15:23 min - 9

Verificando nuestro JWT firmado y buenas practicas con JWT
11:43 min - 10

Server-Side vs Client-Side sessions
05:23 min - 11

Protegiendo nuestros recursos con JWT
04:38 min - 12

Habilitando CORS en nuestro servidor
01:11 min - 13

Profundizando el concepto de JWKS
02:24 min
OAuth 2.0
- 14

Cómo elegir el flujo adecuado para OAuth 2.0
02:54 min - 15

¿Qué es OAuth 2.0?
00:15 min - 16

Conociendo el API de Spotify
07:29 min - 17

Creando los clientes de Spotify y servicios iniciales
16:46 min - 18

Implementando Authorization Code Grant
14:54 min - 19

Usando nuestro access token para obtener nuestros recursos
07:12 min - 20

Implementando Implicit Grant
09:11 min - 21

Implementando nuestro servicio de autenticación
08:46 min - 22

Modificando nuestro Layout
09:18 min - 23

Implementando Client Credentials Grant
09:52 min - 24

Implementando Resource Owner Password Grant
01:46 min - 25

Implementando Authorization Code Grant (PKCE)
Viendo ahora
Open ID Connect
Preocupaciones con JWT y OAuth 2.0
Haciendo uso de Auth0
Consideraciones para producción
Cierre del curso
Authorization Code Grant tiene algunos problemas de seguridad cuando se implementa en aplicaciones nativas. Por ejemplo, un atacante malicioso puede interceptar el authorization_code retornado por el Authorization Server y usarlo para obtener un Access Token.
La Proof Key for Code Exchange (PKCE), definida en https://tools.ietf.org/html/rfc7636, es una técnica usada para mitigar la intercepción del authorization_code.
Con PKCE la aplicación crea, por cada petición de autorización, una llave criptográfica aleatoria llamada code_verifier y su valor transformado llamado code_challenge el cual es enviado al Authorization Server para obtener un authorization_code y posteriormente enviarlo junto con el code_verifier para obtener un Access Token.
Conociendo el flujo
- La aplicación nativa inicia el flujo y redirecciona al usuario al Authorization Server enviando los parámetros
code_challengeycode_challenge_method. - El Authorization Server redirecciona el usuario a la aplicación nativa con un
authorization_codeen el query string. - La aplicación nativa envía el
authorization_codey elcode_verifierjunto con la url de redireccionamiento (redirect_uri) y elclient_idal Authorization Server. - El Authorization Server valida la información y retorna un Access Token.
- La aplicación nativa ahora puede usar el Access Token para llamar los recursos en nombre del usuario (API).
Detalles de implementación
Vamos a ver los detalles de implementación usando JavaScript/Node.js, ya que son operaciones y request básicos que puede implementar cualquier lenguaje nativo. Para ver más detalles de una implementación especifica en lenguajes como Java o Swift pueden consultar una guía aquí.
- Necesitamos generar y almacenar un
code_verifier.
function base64URLEncode(str) { return str .toString("base64") .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=/g, ""); } const verifier = base64URLEncode(crypto.randomBytes(32));
- Mediante el
code_verifiergeneramos uncode_challengeque será enviando en el llamado de autorización.
function sha256(buffer) { return crypto .createHash("sha256") .update(buffer) .digest(); } const challenge = base64URLEncode(sha256(verifier));
- Para comenzar el Authorization Code Grant (PKCE), nuestra aplicación nativa deberá enviar primero el usuario a la url de autorización incluyendo el
code_challengey el método usado para su generación y así obtener elauthorization_code.
https://<authorization-server>/authorize? audience=<your-audience>& scope=<your-scopes>& response_type=code& client_id=<your-cient-id>& code_challenge=<code-challenge>& code_challenge_method=S256& redirect_uri=<your-redirect-uri>
- Ahora que nuestra aplicación tiene el
authorization_codelo debemos cambiar por un Access Token que puede ser usado para hacer llamados a los recursos del usuario. Para ello obtenemos elauthorization_code(code) de nuestro paso anterior y hacemos un llamado tipoPOSTal endpoint de obtención de token enviando también elcode_verifier.
const request = require("request"); const options = { method: "POST", url: "https://<authorization-server>/oauth/token", headers: { "content-type": "application/json" }, body: '{"grant_type":"authorization_code","client_id": "<your-client-id>","code_verifier": "<your-code-verifier>","code": "<your-authorization-code>","redirect_uri": "<your-redirect-uri>"}' }; request(options, function(error, response, body) { if (error) throw new Error(error); console.log(body); });
La respuesta tiene un JSON Web Token, generalmente de tipo Bearer:
{ "access_token": "eyJz93a...k4laUWw", "token_type": "Bearer" }
- Ya teniendo nuestro Access Token podemos hacer llamados a los recursos del usuario (API) en nombre de él.
const request = require("request"); const options = { method: "GET", url: "https://someapi.com/api", headers: { authorization: "Bearer <access-token>", "content-type": "application/json" } }; request(options, function(error, response, body) { if (error) throw new Error(error); console.log(body); });
Con esto tenemos los conocimientos necesarios para poder implementar este flujo. Recuerda seguir las recomendaciones para darle un uso adecuado.