Mostrando entradas con la etiqueta autenticación. Mostrar todas las entradas
Mostrando entradas con la etiqueta autenticación. Mostrar todas las entradas

2 de septiembre de 2011

El protocolo de autenticación OAuth. Métodos de firma (IV)


En la entrada anterior del hilo vimos cuál es el proceso que sigue un usuario para autorizar a una aplicación cliente acceder a sus recursos. A partir de ese momento, todas las peticiones que la aplicación cliente realiza al servidor identifican tanto a ésta como al usuario pero ¿cómo hace para que el servidor sepa con qué usuario se corresponde y a través de qué aplicación está accediendo? Fácil, por medio de firma digital.

OAuth soporta tres tipos de "firma" digital: HMAC-SHA1, RSA-SHA1 y PLAINTEXT (aunque éste último no es un tipo de firma como ahora veremos, de ahí las comillas). El método de firma a utilizar en cada caso depende únicamente de la elección que haga el servidor, ya que son las aplicaciones cliente las que tienen que adaptarse a la implementación que se haya hecho de OAuth. De este modo los servidores, al publicar sus APIs, especifican el tipo o tipos de firma que soportan.

Aquellos que sepan algo de criptografía y conozcan los algoritmos de firma digital sabrán que para llevarse a cabo hace falta, por un lado, una cadena o un mensaje que será lo que se va a firmar y, por otro lado, una clave con la que realizar la firma. En el caso de utilizar un algoritmo de firma simétrica, será necesario que la clave la conozcan ambas partes de la comunicación para que una pueda verificar que la firma de la otra parte es correcta. Sin embargo, si se utiliza firma asimétrica, la parte firmante utilizará su clave privada (que es secreta) para que el destinatario pueda verificarla con la clave pública que recibió anteriormente.

En el caso de OAuth, el algoritmo simétrico soportado es HMAC-SHA1 mientras que el asimétrico es RSA-SHA1. En ambos casos, la cadena (el mensaje) que se firma se calcula de la misma forma, que viene a ser la concatenación (por medio de '&') del método HTTP utilizado en la petición (GET, POST, PUT, DELETE...), la URI base normalizada y un listado de todos los parámetros enviados en la petición ordenados y normalizados.

Entre los parámetros no sólo se incluyen aquellos que van por GET o POST, sino también partes de la cabecera HTTP Authorization, que es a través de la que se suelen enviar los parámetros de OAuth (aunque también se pueden añadir en la URL o en el cuerpo de la petición).

Vamos a verlo con un ejemplo. Imaginad la siguiente petición HTTP:

POST /recurso.html?param_GET=value1 HTTP/1.1
Host: example.com:443
Content-Length: 17

param_POST=value2

Antes de generar la cadena, tenemos que añadirle los parámetros OAuth que servirán para identificar esta petición. Dichos parámetros son:

  • oauth_consumer_key: el consumer key asociado al cliente.
  • oauth_nonce: un token de petición que será único (en combinación con el timestamp, consumer_key y token).
  • oauth_signature_method: método de firma utilizado (HMAC-SHA1, RSA-SHA1 ó PLAINTEXT).
  • oauth_timestamp: Unix timestamp del momento de la petición.
  • oauth_token: access token del usuario (del resource owner).
  • oauth_version: versión de OAuth. Lo más normal es que sea "1.0"

Ahora sí, la cadena resultante será (con valores de ejemplo para los parámetros anteriores):

POST&https%3A%2F%2Fexample.com%2Frecurso.html&oauth_consumer_key%3Dg1S1C08SXq2j%26oauth_nonce%3DT45y1iVuU56v%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1314969840%26oauth_token%3D1KbuMvTOPSA3%26oauth_version%3D1.0%26param_GET%3Dvalue1%26param_POST%3Dvalue2

Ahora aplicamos el algoritmo de firma que hayamos seleccionado (en el ejemplo HMAC-SHA1). En este caso, la clave se construye concatenando (&) el consumer secret y el access secret: Cj6mkF3ug1Ac&eAPJQ9g8xh2B. De manera que el resultado de la firma es (en base64):

N+T8THCg9CHknmt50UNTPZE3ZAk=

Al final, la petición quedaría de la siguiente manera:

POST /recurso.html?param_GET=value1 HTTP/1.1
Host: example.com:443
Authorization: OAuth realm="https://example.com/recurso.html",
    oauth_consumer_key="g1S1C08SXq2j",
    oauth_token="1KbuMvTOPSA3",
    oauth_nonce="T45y1iVuU56v",
    oauth_timestamp="1314969840",
    oauth_signature_method="HMAC-SHA1",
    oauth_version="1.0",
    oauth_signature="N%2BT8THCg9CHknmt50UNTPZE3ZAk%3D"
Content-Length: 17

param_POST=value2

De este modo, en la petición se recoge desde qué aplicación se está accediendo (consumer key y consumer secret) y en nombre de qué usuario (access token y access secret). Además se provee de integridad en la petición por el simple hecho de ir firmada y de un mecanismo contra ataques de replay (reenvío de peticiones) por medio del nonce y el timestamp.

En el caso de RSA-SHA1, se utiliza el algoritmo RSASSA-PKCS1-v1_5:

oauth_signature = RSASSA-PKCS1-v1_5 (K, M)

siendo M la cadena que hemos creado antes y K la clave RSA privada del cliente.

El caso de PLAINTEXT es diferente debido a que no se llega a firmar ninguna cadena. En este caso, el valor del parámetros oauth_signature se construye como la concatencación (&) consumer secret y el access secret, que se envían en texto plano.

Como podréis imaginaros, este mecanismo sólo es recomendable en el caso de utilizar un canal seguro como pueden ser SSL o TLS. De no ser así (o si se llevara a cabo un ataque Man-in-the-Middle), se podrían suplantar las identidades del cliente y del usuario ante el servidor; es decir, se podría acceder a los recursos del usuario en nombre del cliente.

Si queréis ver cómo funciona todo esto de un modo más práctico, os recomiendo el siguiente enlace:

http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iv-signing-requests/

¡Hasta la próxima entrada!

8 de agosto de 2011

El protocolo de autenticación OAuth. Flujo de Autenticación (III)


Una vez que conocemos los actores que intervienen en la autenticación por OAuth, veamos cómo se lleva a cabo.

Cuando queremos desarrollar una aplicación (un cliente) para un servicio (twitter para continuar con nuestro ejemplo de la entrada anterior), lo primero que hay que hacer es registrar la que será nuestra aplicación. En ese momento, twitter nos dará un par de credenciales de cliente (o lo que es lo mismo, el consumer key y el consumer secret) con las que nuestra aplicación deberá firmar todas las peticiones que realice a los servidores de twitter.

Veamos el flujo completo en el siguiente diagrama. Las flechas de color rojo se corresponden con las peticiones que realiza el cliente a twitter. Las verdes son respuestas de twitter al cliente. La flecha de color azul se corresponde con el proceso que realiza el usuario a mano:

Flujo OAuth.

Cuando un usuario quiera utilizar nuestro cliente, lo primero que tendrá que hacer éste último es solicitar a twitter unas credenciales temporales (request token y request secret). Este proceso se corresponde con los pasos 1 y 2 del diagrama.

A continuación, nuestro cliente redirigirá al usuario a la Web de twitter (paso 3) indicando el request token que se nos ha facilitado. El usuario inicia sesión en twitter, que le preguntará si autoriza a nuestra aplicación a acceder a sus recursos (paso 4).

Suponiendo que el cliente autorice la aplicación, twitter redirigirá de vuelta al usuario a nuestro cliente si éste se tratara de una aplicación Web (paso 5). En esta petición se indicará un PIN denominado oauth_verifier que será utilizado más adelante.

Para que la redirección sea posible, cuando se solicitan las credenciales temporales en el paso 1, también se indica la URL a la que queremos que twitter redirija al usuario.

En el caso de que nuestro cliente sea una aplicación de escritorio, de teléfono móvil, etc. (en general cualquiera a la que no se pueda realizar la redirección) se sustituye la URL de callback por el valor "oob" (out-of-band). Esto indicará a twitter que basta con que comunique al usuario el oauth_verifier para que sea éste quien lo introduzca directamente en el cliente.

Una vez que el cliente conoce el oauth_verifier, lo envía de vuelta a twitter para solicitar el token de usuario. El servidor responderá a esta petición con el access token y access secret (pasos 6 y 7), lo que finaliza la autenticación por OAuth.

Todas las peticiones que el cliente realice a partir de ese momento, irán firmadas por una combinación del consumer secret y el access secret. De este modo, se identifica en todo momento al usuario y el cliente desde el que se realiza la petición y, de este modo, twitter puede determinar a qué información puede tener acceso y a cuál no.

El flujo descrito es el proceso de autenticación habitual a través de OAuth pero no es el único. Éste se conoce como 3-legged porque en él intervienen los tres actores habituales. Otro flujo que se suele utilizar es el llamado 2-legged en el que el usuario no interviene (sólo hay que autenticar a la aplicación) debido a que no se accede a sus recursos.

¡Hasta la próxima entrada!

1 de agosto de 2011

El protocolo de autenticación OAuth. Conceptos (II)

Cuando se lee documentación sobre OAuth se ven una serie de conceptos que, aunque sencillos, en algunos casos pueden llevar a confusiones debido a que la terminología se modificó en algún punto del desarrollo. De esta manera, hay documentos que utilizan la terminología "antigua" mientras que la RFC oficial y la mayor parte de documentos recientes utilizan los términos actuales.

twitter es un servicio que utiliza OAuth para llevar a cabo la autenticación de usuarios desde aplicaciones de terceros, ya sean Web, de escritorio o para dispositivos móviles. Por este motivo, voy a utilizar twitter como ejemplo para identificar cada uno de los términos que paso a describir:

Servidor /server/ (inicialmente llamado Service Provider)
Es quien proporciona el servicio; es decir, allí donde nos estamos intentando autenticar para acceder a sus funcionalidades. En nuestro caso serían los propios servidores de twitter.

Cliente /client/ (antes llamado Consumer)
Es la entidad desde la que se lleva a cabo la autenticación. Cualquier cliente de escritorio, extensión de navegador, cliente para dispositivos móviles... que trabaje con twitter se considera un cliente. Por tanto, se puede decir que es la "aplicación de terceros" desde la que intentaríamos acceder a nuestra información en twitter.

Dueño o Propietario del recurso /Resource Owner/ (antes llamado User)
Como el propio nombre indica, es el propietario del recurso al que se quiere acceder. En nuestro ejemplo seríamos los usuarios finales de twitter.

De esta última definición se puede deducir un nuevo concepto: Recurso protegido /Protected resource/ que sería el recurso (información, funcionalidad...) ubicado en el Servidor al que estamos intentando acceder y que pertenecería a su Propietario.

Por otro lado, se suele diferenciar entre tres tipos de credenciales: cliente, temporales y token. Todas ellas se están formadas por un identificador único y por un secreto (algo parecido al típico usuario/contraseña, aunque no es del todo igual).

Como sucedía con los conceptos anteriores, en alguna documentación se puede encontrar otros nombres para cada par de los anteriores credenciales. De este modo tendríamos consumer key y secret (cliente), request token y secret (temporales) y access token y secret (o incluso user token y secret para el token).

Las credenciales de cliente se utilizan para que el servidor pueda identificar a un cliente determinado. De este modo, el servidor sabe en todo momento qué tipo de cliente está accediendo y podría dar funcionalidades extra a clientes de confianza o con ciertos privilegios. En el caso de twitter, ésta avisó de que toda aplicación que publicara sus credenciales clientes sería deshabilitada (lo siento pero no encuentro la noticia).

Las temporales se utilizan durante el proceso de autenticación de un usuario final (dueño del recurso) y, como su propio nombre indica, su validez es temporal mientras se acuerda el token que será utilizado durante la sesión.

El token sería el equivalente a un identificador de sesión en una aplicación Web estándar y se utiliza para identificar tanto al cliente como al usuario que accede a sus recursos.

Creo que por hoy ya está bien. En la próxima entrada explicaré cómo se obtienen cada una de estas credenciales y cómo interactúan las partes implicadas.

¡Hasta la próxima!