SlideShare uma empresa Scribd logo
1 de 20
Baixar para ler offline
Entendiendo oAuth
      Una breve explicación sobre oAuth 1.0
                         Eduard Tomàs (@eiximenis en twitter)
                                      4/28/2012




Este documento es una breve introducción a oAuth, comentando brevemente como funciona
el procolo en su versión 1.0a y mencionando los distintos flujos de oAuth existentes
Entendiendo	OAuth
Contenido
¿Qué es OAuth? ........................................................................................................................ 2
   La necesidad de OAuth .......................................................................................................... 2
Tokens, tokens, tokens.............................................................................................................. 3
   Criptografía para dummies.................................................................................................... 3
       Dos amigos... ..................................................................................................................... 4
       ...y el novio celoso. ............................................................................................................ 5
       Firmas digitales ................................................................................................................. 6
   Firma de peticiones en OAuth ............................................................................................... 8
       Tipo de tokens OAuth ........................................................................................................ 9
       Normalización de peticiones ........................................................................................... 11
       Creación de la cadena base de firma ............................................................................... 12
       El método de codificación percent encoding .................................................................... 12
Elementos de una petición OAuth ........................................................................................... 13
   Parámetros OAuth .............................................................................................................. 13
   Localización de los parámetros OAuth ................................................................................. 14
       Cabecera Authorization ................................................................................................... 14
Flujos de OAuth ...................................................................................................................... 15
   3-legged OAuth ................................................................................................................... 15
   Cliente escritorio – Autenticación por PIN ........................................................................... 16
   Cliente escritorio – autenticación por password .................................................................. 17
   2-legged OAuth ................................................................................................................... 17
   Pseudo-autenticación con OAuth ........................................................................................ 17




Desde ya hace un tiempo se oye hablar mucho de OAuth. Casi cualquier red social o aplicación
web que exponga una API pública para desarrolladores expone sus servicios usando este
protocolo. ¿Quieres integrarte con Twitter, Linkedin, Facebook o Google+, entre muchas
otras? Todas ellas requieren usar OAuth para poder utilizar sus servicios.
El objetivo de este documento no es que puedas aprender a crear un cliente que use OAuth,
para ello no hay mejores tutoriales que los propios que desarrollan los creadores de servicios
(créeme: ellos son los primeros interesados en que uses sus servicios). Tampoco es objetivo de
este documento explicar todos los pormenores de OAuth (para ello hay una especificación
oficial). Entonces... ¿cuál es el objetivo? Pues simple y llanamente: que entiendas OAuth. Que
entiendas qué es OAuth, cuál es su motivación, que problemas permite solucionar y que otros
puede llegar a plantear. Por supuesto vamos a entrar en detalles sobre el funcionamiento de
OAuth, aunque para descripciones detalladas referenciaremos a la RFC. Y sí, también veremos
cómo crear un cliente OAuth y por encima de todo un proveedor de OAuth y cómo integrarlo
en nuestras aplicaciones web usando, en este caso, ASP.NET MVC.
Si te interesa el tema, y quieres conocer OAuth en lugar de simplemente usarlo... este
documento es para ti.


¿Qué es OAuth?
Resumiendo, OAuth es un protocolo de autorización (su nombre proviene de Open
Authorization), que permite a un usuario (propietario de ciertos recursos) autorizar a un
tercero a que acceda a dichos recursos en su nombre pero sin darle en ningún momento a este
tercero sus credenciales de autenticación (es decir, sin darle a este tercero su nombre de
usuario ni contraseña).
Actualmente está en su versión 1.0a y se está desarrollando la versión 2.0 que va a ser
incompatible con la versión anterior. Dicha versión 2.0 debería haberse finalizado a finales del
2011, pero sigue estando todavía en desarrollo y sin fecha prevista de finalización. La principal
mejoras de OAuth 2.0 respecto a 1.0a son que es más fácil de usar para el usuario. Este
documento se basa en OAuth 1.0.
Aun cuando OAuth es un protocolo de autorización es posible conseguir una pseudo
autenticación con él, y de hecho uno de usos más extendidos es el de entrar en una aplicación
web usando el usuario y contraseña de otra aplicación. De esta manera grandes proveedores
de OAuth, como Facebook, se convierten a su vez en proveedores de autenticación de otras
webs. Así, paradójicamente, OAuth está teniendo éxito donde otros protocolos más orientados
a autenticación como OpenID o anteriormente Passport (actual Live ID) no han terminado de
tenerlo. Esto nos demuestra una vez más, que el éxito de un producto (un protocolo en este
caso) viene muchas veces marcado por quien lo adopta, y el momento en que lo adopta, más
que en las características técnicas de éste. Esta es una lección que solemos olvidar demasiado
a menudo.

La necesidad de OAuth
La necesidad de un protocolo de autorización como es OAuth suele ser la confianza. O mejor
dicho, la falta de ella. El hecho de que yo como usuario no confíe en una aplicación lo
suficiente como para darle mis datos de autenticación pero por otro lado quiera permitir que
dicha aplicación realice algo en mi nombre. Y no es lo mismo realizar algo en el nombre de
alguien, que suplantar a este alguien. Esto es precisamente lo que permite OAuth: que alguien
realice tareas en nombre de otro, pero sin poder suplantarlo: en todo momento se sabe quién
es realmente el que está realizando las tareas. Al tener la autorización separada de la
autenticación, yo puedo en cualquier momento desautorizar a quien yo haya autorizado
previamente. Es decir, impedir que siga realizando tareas en mi nombre. Y puedo hacer esto
sin necesidad de modificar mi usuario o contraseña.
Y desde el punto de un proveedor de servicios... ¿Qué le ofrece OAuth que motive el usarlo?
Pues precisamente el hecho de querer generar un ecosistema de terceros que usen sus
servicios. Pongamos como ejemplo a Facebook. Facebook no expone su API para su propia
aplicación móvil, la expone básicamente para permitir todo un desarrollo de un ecosistema de
aplicaciones integradas en Facebook, pero realizadas por otros. Es una relación win-win entre
Facebook y el creador de la aplicación. El segundo puede aprovechar todo el potencial social
que Facebook puede generar, y el primero obtiene más interacciones que es lo que más
necesita una red social. Por supuesto que todo esto se podría conseguir sin OAuth, pero en
unos tiempos donde se están mandando tantos (acertados) mensajes contra el phising y
continuamente se nos dice que vigilemos nuestras credenciales y que no nos fiemos, no
quedaría muy bien que cualquier web o aplicación nos pidiese el usuario y contraseña de
Facebook... ¿Qué hará con ellos? ¿Cómo tengo yo la seguridad, como usuario, de que la
aplicación es bienintencionada? Además, incluso en el caso de que la aplicación fuese
bienintencionada, el que todas mis aplicaciones conectadas a Facebook tengan mi usuario y
contraseña implica que si alguna vez, por cualquier razón, los modifico deba informar a todas
esas aplicaciones de nuevo. Como veremos más adelante OAuth me permite obviar todo esto.
Así pues, OAuth expone claras ventajas tanto para usuarios como para desarrolladores de
servicios. Ha llegado el momento de ver, someramente, como funciona.


Tokens, tokens, tokens
La verdad es que OAuth va, básicamente, sobre intercambiar tokens. Hay tres roles que
debemos considerar:

       El cliente, que quiere acceder a un servicio en nombre de un usuario. Este cliente
        puede ser una aplicación web, móvil o de escritorio.
       El proveedor de servicios, que provee el servicio al cual quiere acceder el cliente
       El autenticador que autentica los usuarios

Lo que OAuth define es como esos tres roles deben comunicarse entre ellos para que al final el
cliente pueda acceder al servicio. Lo que no define OAuth es como el autenticador realiza su
trabajo (es decir, como se autentica el usuario).
El objetivo final es que el cliente consiga lo que desde siempre se ha llamado Access token
(aunque en la RFC decidieron modificar todos los nombres y lo llamaron Token Credentials).
Enviando este token el cliente puede acceder a un recurso protegido en nombre del usuario
que haya autenticado el autenticador.

Criptografía para dummies
Antes de meternos de lleno en OAuth, dado que vamos a hablar de firma digital y métodos
criptográficos de clave simétrica o asimétrica déjame que te hable un poco sobre conceptos
elementales de criptografía. Si conoces que son los métodos de clave simétrica, asimétrica y la
firma digital, eres libre de saltarte este apartado :) Y por supuesto, si encuentras todo el tema
de la criptografía aburrido y falto de interés te lo puedes saltar también, en el fondo no es
necesario conocerlo para poder usar OAuth... Aunque sí para entenderlo realmente, y como de
eso se trata, si te apetece… ¡allá vamos!
Dos amigos...
Imaginemos a dos amigos, Alice y Bob que quieren enviarse un mensaje codificado sin que
nadie más pueda descifrarlo. Hay muchos mecanismos de encriptación que pueden utilizar,
pero los podemos dividir en dos grupos: de clave simétrica y de clave asimétrica.
Los de clave simétrica son los primeros que nos vienen a la cabeza cuando pensamos en
mecanismos de codificación. Tenemos una función (f) que dada una clave (K) y un texto a
codificar (t) devuelve el texto codificado (t’). Entonces se cumple que:
         ( , )=
         ( , )=

Es decir, para cifrar y descifrar se usa la misma clave.
Ahora supongamos que Alice y Bob quieren mantener una conversación privada y para ello
deciden cifrarla. Lo primero que tienen que hacer es quedar de acuerdo en la clave a usar.
Bastaría con un correo de Alice proponiendo la clave y uno de Bob aceptándola. A partir de
este punto ambos usan la misma clave y la conversación puede tener lugar.
Si has arrugado la nariz cuando he mencionado que Alice envíe un correo con la clave es que
has visto el punto débil de los métodos de clave simétrica: el intercambio de la clave. Es un
punto muy delicado, ya que si alguien (un tal Mallory que os presentaré luego) descubre la
clave, toda la conversación entre Alice y Bob está comprometida.
Es aquí donde entran en juego los mecanismos de clave asimétrica.
Dichos mecanismos se basan en algo muy simple (pero a la vez muy potente): la capacidad de
generar dos pares de claves, ligadas de algún modo entre sí, de forma que al codificar algo con
una de las claves se pueda decodificar con la otra y viceversa. Así pues si tenemos un par de
claves, llamémoslas A y B, un texto (t) a codificar y una función (f) que dado una clave y un
texto devuelve un texto codificado, se cumple que:
            , ( , ) =        , ( , ) =

Y no sólo eso, si no que la relación NO es reflexiva:

           , ( , ) <>
           , ( , ) <>

Cada uno de ellos por separado y sin comunicárselo a nadie genera un par de claves (A,B). En
este momento Alice tiene su par de claves y Bob las suyas. Posteriormente ambos se envían
por mail una sola de esas claves (pongamos la A), a la que llamaremos la clave pública. La otra
clave del par de claves, se la guardan para ellos mismos y no la dicen a nadie así que la
llamaremos la clave privada. De hecho, cualquiera que más adelante quisiera enviar mensajes
a Bob, como su amigo del instituto Charlie, debe pedirle a Bob que le dé la clave pública. Tan
solo esa.
En este momento, Bob pondría enviar un mensaje a Alice, encriptado con la clave pública de
ella. El resultado es un mensaje que solo puede decodificar quien posea la otra clave del par
de claves. Y dado que Bob ha usado la clave pública de Alice, quien posee la otra clave del par
de claves es la propia Alice: se trata de su clave privada. De este modo Bob ha conseguido
enviar un mensaje que solo Alice puede entender. ¿Y si ahora Alice quiere responder el
mensaje? Pues muy simple: tan solo debe cifrarlo usando la clave pública de Bob, para que
este al recibirlo use su clave privada y pueda descifrarlo.
Resumiendo, la idea es muy simple: se cifra el mensaje con la clave pública del receptor, el cual
debe usar su clave privada (que solo conoce él) para descifrarlo.
Este sistema asegura cifrado y descifrado seguro de los mensajes (tan seguro como sea el
algoritmo de encriptación que se use, pero eso es otra historia). Pero existe un riesgo que
debemos tener presente.

...y el novio celoso.
¿Recordáis que antes mencionamos a Mallory? Dejadme que os lo presente: es el novio de
Alice. Aunque es un buen tipo, es extremadamente celoso y como cree que Bob tiene
intenciones poco honestas con Alice hace tiempo que está espiando lo que ella hace. En el
fondo Mallory no le tiene manía a Bob: cree que todo el mundo quiere algo con Alice más allá
de la amistad.
A priori puede parecer que el mecanismo de encriptación basado en clave asimétrica les
protege del todo: la única clave que circula al principio de la conversación entre Alice y Bob es
la clave pública de cada uno de ellos que solo sirve para cifrar, nunca para descifrar, así que
aunque Mallory supiese la clave pública no podría hacer nada (a diferencia de un mecanismo
de clave simétrica, ya que en este caso si Mallory descubre la clave puede descifrar toda la
conversación). En efecto, es cierto que si Mallory tan solo conoce las claves públicas de ambos
no puede comprometer la seguridad de la comunicación de los dos amigos... Pero esta certeza
no es garantía de una seguridad absoluta.
Y es que Mallory instaló un proxy conectado a su propio ordenador que le permite tener
acceso e interceptar todo lo que su novia envía y recibe desde internet (sí, los celos son muy
malos). Gracias a esto Mallory intercepta el correo en el que Alice le pedía a Bob su clave
pública y deja que llegue a Bob. Bob recibe el mensaje que proviene de Alice y le contesta con
su clave pública. Dicho mensaje es interceptado de nuevo por Mallory, quien cambia la clave
pública de Bob por la suya, se guarda la clave pública de Bob y reenvía el mensaje a Alice. En
este punto Alice cree tener la clave pública de Bob, pero realmente tiene la de su novio.
Así cuando Alice quiere decirle algo a Bob, lo encripta con la clave pública de este... o con lo
que ella cree que es la clave pública de Bob. Porque realmente es la de Mallory, el cual puede
descifrarlo (usando su clave privada), modificarlo, cifrarlo de nuevo (usando la clave pública de
Bob que se ha guardado antes) y reenviar el mensaje a Bob, quien creerá que el mensaje
proviene de Alice.
Este tipo de ataques, en el cual un tercero (Mallory) puede interceptar, leer y modificar
mensajes que se envían un par de actores (Alice y Bob) sin que ninguno de ellos pueda saber
que su seguridad ha sido comprometida se llaman ataques Man-in-the-Middle.
El error de Bob y Alice ha sido permitir que Mallory interceptara un único mensaje: el que
usaron para intercambiar sus claves. Este es el punto débil de todo sistema de criptografía: el
intercambio de claves (sí, incluso en los asimétricos donde podríamos creer que evitaban este
problema).
Amigo lector, por si lo has pensado, una solución muy rápida que evitaría los trapicheos de
Mallory, sería evitar que hubiese intercambio de claves públicas al inicio de la conversación
entre Bob y Alice. Si ambos publicasen su clave pública en una web, a la vista del todo el
mundo, Mallory no podría interceptar ningún mensaje y sustituir las claves porque este
mensaje no existiría: cuando Alice quisiera ver la clave pública de Bob la miraría en esta web y
viceversa. Claro que en este caso tanto Alice como Bob deben tener estar seguros de que la
web donde publican sus claves públicas es de confianza. No vaya a ser que le encarguen hacer
la web a Chuck, un antiguo compañero de fiestas de Mallory, con lo que estarían igual que
antes. Pero si la web es de una empresa que ofrece este servicio (hospedar claves públicas), y
que ofrece absolutas garantías de seguridad, entonces sí que Mallory no tiene nada que hacer
y Alice y Bob pueden estar tranquilos... Y aunque pueda parecer muy tonto, esto de publicar
las claves públicas de todos en un sitio común, es más o menos lo que hacemos actualmente
con los certificados digitales y las infrastructuras de clave pública (PKI).

Firmas digitales
Si has entendido como funciona la encriptación, ya estás listo para comprender como funciona
la firma digital. El concepto de firma digital es extremadamente sencillo: se trata de aplicar una
función de hash al documento y cifrar tan solo el hash. El hash cifrado constituye la firma
digital.

Funciones de hash
Si Bob quiere enviar un documento firmado digitalmente, debe calcular el hash de este
documento. El hash no es más que aplicar una función que devuelva un valor resumen que
dependa de los datos del documento. Lo de resumen viene porque generalmente el tamaño
en bytes del documento suele ser superior al tamaño en bytes del hash.
Así una posible función de hash sería sumar los códigos ASCII de todos los caracteres del
documento y realizar el módulo 256. Con esto obtendríamos un número de 0 a 255. Fijaos que
convertimos textos de cualquier número de byes a valores de un solo byte, de ahí lo de
resumen. Dada esa función de hash, el hash del texto Hola seria 132.
Por supuesto esta es una función de hash horrorosa, seguro que no te cuesta nada encontrar
otro texto distinto que dé el mismo valor de hash. Es evidente que, por norma general,
siempre habrá más documentos que hash posibles (en nuestro caso hay infinitos documentos
posibles y tan solo 256 hash), por lo que habrá colisiones (es decir dos documentos distintos
que generen el mismo hash). Lo que distingue una buena función de hash de una de mala es lo
que cueste encontrar dos documentos distintos que generen un mismo hash (lo que en
criptografía se conoce como resistencia a las colisiones y que mide cuan resistente es una
función de hash frente a lo que se conoce como un ataque de cumpleaños).
Suponiendo una función de hash con alta resistencia a las colisiones (es decir que sea inviable
encontrar dos elementos que den el mismo hash) entonces Bob puede firmar un documento
de la siguiente manera:
    1. Calcula el hash del documento
    2. Cifra el hash y obtiene la firma digital.
    3. Envía el documento junto con la firma digital.
Lo importante aquí es que el documento no tiene por qué estar encriptado (puede estarlo pero
no es obligatorio). Lo que está cifrado usando la clave privada de Bob es el hash y eso
constituye la firma digital. Cuando el receptor reciba el documento debe:
    1. Descifrar la firma digital para obtener el hash
    2. Calcular por su parte el hash del documento (usando la misma función de hash)
    3. Comparar ambos valores (el hash descifrado y el hash calculado)

Si ambos valores coinciden la firma digital del documento es válida… ¿y qué significa
exactamente esto? Pues depende del mecanismo de cifrado que se use para cifrar el hash.

Firmas con mecanismos asimétricos vs firmas con mecanismos simétricos
A grandes rasgos: una firma digital correcta indica que el documento no ha sido modificado
por nadie a excepción de un remitente válido y que ha sido enviado por un remitente válido. Lo
que significa exactamente “remitente válido” varía en función de si para cifrar el hash se usó
un mecanismo con claves simétricas o asimétricas.
Si se ha usado un mecanismo con claves asimétricas, remitente válido es aquel que ha enviado
el documento. Nadie más. Debe notarse que decimos aquel que ha enviado el documento, no
aquel que legítimamente puede leerlo. Si en el ejemplo anterior Bob hubiese usado un
mecanismo de cifrado asimétrico podemos afirmar que el documento no ha sido alterado (lo
que se ha recibido es lo que se ha enviado) por nadie más. No solo eso, si no que además se
puede asegurar que ha sido Bob quien lo ha enviado (o dicho a la inversa, Bob no puede negar
haber enviado el documento, lo que se conoce como no repudio). Si alguien intercepta el
documento y lo modifica, dado que no puede modificar la firma digital (ya que está cifrada con
la clave privada de Bob que tan solo tiene él), cuando el receptor reciba el mensaje el hash que
él calcule diferirá del que venía con el documento, con lo que se sabrá que ha sido
interceptado y modificado.
Si se ha usado un mecanismo de clave pública, entonces “remitente válido” significa cualquiera
que conozca la clave. Es decir cualquiera que pueda recibir un mensaje y calcular la firma
digital. Si Bob calcula su firma digital cifrando el hash con un mecanismo de clave simétrica, es
evidente que Alice debe conocer la clave para poder descifrar el hash y compararlo con el que
obtenga ella para validar la firma digital. Pero dado que la clave que se usa para descifrar es la
misma para cifrar y que Alice también la tiene, nada impide que Alice modifique el documento,
vuelva a calcular el hash y lo cifre de nuevo usando la misma clave. En este caso no podemos
pues asegurar unívocamente como antes que lo ha enviado Bob. Puede haberlo enviado Alice.
No hay manera de saberlo. La firma digital sigue asegurando, eso sí, que si el mensaje es
modificado por alguien que no conoce la clave de cifrado, el resto de participantes que sí la
tienen se darán cuenta de que el mensaje ha sido modificado. Digamos que, usando un
mecanismo cifrado de clave simétrica, todos los participantes válidos son tratados como una
misma persona.

Seguridad de la firma digital
Fíjate que la asunción principal que se realiza de la firma digital (se puede asegurar que el
documento no ha sido modificado), depende directamente de que la función de hash tenga
una alta resistencia a las colisiones. De hecho lo que debe evitarse es que sea factible para
alguien generar un par de documentos (uno auténtico y otro fraudulento) que tengan el
mismo hash1. Si eso es factible (a nivel computacional) de realizar, alguien, llamémosla Carol,
podría presentar el documento auténtico a Bob, quien lo firmaría y luego podría añadir la
firma digital de Bob al documento fraudulento, con lo que a todos los efectos sería como si
Bob hubiese firmado dicho documento falso.
El propósito de la firma digital no es evitar que alguien intercepte el mensaje, si no asegurar
que éste no ha sido alterado en tránsito y que es enviado realmente por el remitente. Si se
quiere evitar que el mensaje sea visible a terceros, este debe además cifrarse. Eso sí, que
quede claro: La firma digital no evita que pueda existir un Man-in-the-middle si el intercambio
de claves ha sido comprometido.
OAuth permite usar tanto mecanismos de clave simétrica como mecanismos de clave simétrica
para cifrar el hash y obtener la firma digital. A la práctica la mayoría de proveedores soportan
tan solo un mecanismo de clave simétrico (HMAC) para evitar todo el proceso de negociación
de claves públicas. Aunque es un poco menos seguro (cualquiera que robe la clave que se use
para cifrar los mensajes podrá enviar mensajes OAuth válidos) evita todo el trasiego de
intercambio de claves públicas.

Firma de peticiones en OAuth
En OAuth todas las peticiones que realiza el cliente van firmadas digitalmente. La
especificación habla explícitamente de tres métodos de firmado:
    1. HMAC-SHA1: Que es un método de firma electrónica basado en la función de hash
       SHA1 y el método de cifrado simétrico HMAC
    2. RSA-SHA1: Que es un método de firma electrónica basado en la función de hash SHA1
       y el método de cifrado asimétrico RSA. La especificación no dice nada sobre como el
       cliente y el proveedor de servicios intercambian sus claves públicas.
    3. PLAINTEXT: No existe firma digital. El valor de la firma digital se sustituye por el valor
       de los tokens secretos (Consumer Secret, Request Secret y Access Secre) que se usen
       en cada momento. Este método es altamente inseguro y de hecho la propia
       especificación ya indica que debe usarse sobre un canal de comunicación seguro (SSL o
       TLS) y tiene su razón de existir en que si se usa uno de esos canales, no es necesario
       añadir un método adicional como la firma electrónica para garantizar que la petición
       no ha sido modificada, dado que el propio canal seguro te lo asegura.
Honestamente, en la especificación no queda muy claro si debe darse soporte a esos tres
métodos o bien puede darse soporte a solo algunos de ellos. Lo que sí dice es que pueden
añadirse métodos adicionales. En la vida real, hay muchos proveedores de OAuth que no
soportan RSA-SHA1 supongo que para evitar el problema de intercambio de claves públicas,
algo que se evita en HMAC-SHA1 al ser este un método asimétrico donde hay una sola clave
compartida y conocida por todos. Personalmente creo que implementar solo HMAC-SHA1 es
una solución más que válida-



1
 Esto es importante: no es peligroso que varios documentos tengan el mismo hash (esto es inevitable,
de hecho). Lo que es peligroso es que sea factible computacionalmente para alguien generar pares de
documentos con el mismo hash.
La necesidad de que en OAuth cada petición vaya firmada es, evidentemente, por seguridad: si
no fuese así, alguien podría interceptar la petición del cliente al proveedor de servicios,
modificarla y reenviarla de nuevo. Precisamente para evitar esto y asegurar que el proveedor
de servicios solo responde a peticiones legítimamente enviadas por un cliente, estas deben ir
firmadas. Esto no evita que alguien pueda ver los datos que se envían entre cliente y
proveedor pero sí evita que puedan ser modificados.
Es importante destacar que la respuesta del proveedor de servicios no va firmada (esto es así
debido a la naturaleza síncrona de http): tan solo se firman las peticiones del cliente. Exacto:
alguien con un sniffer podría modificar las respuestas del proveedor de servicios y el cliente no
se daría cuenta, pero para evitar este escenario ya hay otras alternativas de seguridad
adicionales a OAuth (SSL o TLS sin ir más lejos). Este no es un escenario que intente resolver
OAuth. Quede claro pues que OAuth no es un protocolo de seguridad, ni quiere, ni puede,
garantizar la seguridad o integridad de los datos enviados o recibidos.
Cuando empieces a leer sobre OAuth, verás que continuamente se habla de pares de tokens:
el token público y el secreto (key y secret en inglés). No te confundas: esos pares de tokens,
¡no son pares de claves asimétricas! Realmente uno de ellos (el público) actúa como
identificador y el otro (el secreto) es el que se usa para firmar digitalmente.

Tipo de tokens OAuth

Consumer Key y Consumer Secret
Por lo tanto todo cliente que quiera usar OAuth deberá tener su par de tokens. Quien otorga
estos tokens y como estas son transferidas al cliente está fuera de la especificación de OAuth.
Es decir, OAuth no define ningún mecanismo para que el cliente obtenga su par de tokens.
Simplemente se asume que las tiene, y que ambos tanto cliente como proveedor de servicios
las conocen.
En terminología OAuth llamamos Consumer Key al token que identifica un cliente y Consumer
Secret al token privado que este cliente usará para firmar sus peticiones OAuth. Aunque desde
siempre se han llamado así, en la RFC decidieron modificar el nombre y llamarlos Client
Credentials (credenciales de cliente) nombre que realmente es más acertado.
La especificación no dice nada acerca de como el cliente obtiene sus credenciales, pero en la
práctica lo más normal es tener que registrar el cliente manualmente, en el proveedor de
servicios.
Ilustración 1: Registro de una aplicación cliente en Twitter

La Ilustración 1 muestra el proceso de registro de un cliente en Twitter. Una vez registrado el
cliente Twitter nos informará de nuestras credenciales de cliente, que son las que deberemos
usar. Este método es sencillo y eficaz aunque obliga a registrar cada posible cliente de forma
manual. Tanto Facebook, como LinkedIn como cualquiera de los proveedores de OAuth
ofrecen un mecanismo similar para el registro de clientes.

Request Token y Request Secret
El objetivo final de OAuth es permitir acceder a recursos protegidos en nombre de un usuario
en concreto. Para ello, el cliente debe a partir de sus credenciales de cliente, obtener unos
tokens finales que representen que el usuario ha dado permisos para acceder a esos recursos.
Para ello el primer paso es obtener un par de tokens temporales, que servirán para ir
enlazando toda la serie de peticiones OAuth que son necesarias para obtener los tokens
definitivas (mucha gente se refiere a esa serie de peticiones con el nombre de OAuth Tokens
dance).
El Request Token identifica a una petición de permisos para un usuario en concreto. Cuando el
cliente quiere obtener un token de acceso definitivo, lo que obtiene primero es el Request
Token. Luego manda este Request Token al autenticador, quien (si el usuario acepta los
permisos) le devuelve un código de verificación que luego el cliente puede usar para obtener
los tokens finales (no te preocupes si eso te parece muy lioso ahora, luego aclararemos
completamente el flujo OAuth). Lo importante es que te quedes con la idea de que el Request
Token y el Request Secret son tokens temporales, que son descartados una vez se obtienen los
definitivos.
A lo mejor te estás preguntando por que es necesario un Request Secret. ¿No se supone que
las peticiones van firmadas usando el Consumer Secret como clave para generar la firma
digital? La respuesta es que una vez tenemos Request Token, las peticiones OAuth que
hagamos irán firmadas usando el Consumer Secret y el Request Secret (ambos a la vez).
¡Ah sí! Se me olvidaba: He usado los nombres Request Token y Request Secret que son los que
se usan comúnmente, pero la RFC usa otros nombres que son (de nuevo) mucho más
acertados: Temporary Credentials.

Access Token y Access Secret
El Access Token y el Access Secret (llamados en la RFC Token Credentials) son el objetivo final:
los tokens que se obtienen una vez el usuario se ha validado y ha aceptado los permisos
demandados por el cliente. Una vez el cliente obtiene esos tokens, el flujo de OAuth termina y
el cliente puede empezar a realizar llamadas al proveedor de servicios en nombre del usuario.
El Access Secret se usa para firmar todas las peticiones OAuth que haga el cliente una vez
tenga el Access Token (se usa conjuntamente con el Consumer Secret).
Ahora que ya conoces los tres pares de tokens de OAuth... viene la pregunta clave: ¿qué datos
de la petición se firman?

Normalización de peticiones
La firma digital de un documento (en nuestro caso de una petición http) depende de los datos
que esta contenga. Debemos preguntarnos pues ¿qué define a una petición http?
El primer elemento es la URL, dos peticiones serán distintas si su URL es distinta. Eso significa
que peticiones que solo difieren en la URL (incluso si van a URLs sinónimas como pueden ser
http://www.krasis.com y http://217.130.23.249) van a generar firmas digitales distintas.
Otro elemento son los parámetros de la petición. HTTP permite que las peticiones lleven
parámetros en varios sitios (query string, cuerpo, headers varios), así que OAuth define cuales
son los posibles orígenes de los parámetros. En concreto se tomarán:
    1. Los parámetros de la query string
    2. Los parámetros en el cuerpo de la petición si esta viene como application/x-www-
       form-urlencoded
    3. El valor del header Authorization, si este define que es de tipo OAuth, excluyendo el
       valor de realm si lo hubiese.
Nos queda un tercer elemento. Podemos tener dos peticiones exactamente con la misma URL,
con los mismos parámetros (en el mismo orden y situación si se quiere) pero que sean dos
peticiones distintas si usan un verbo http distinto.
Esos tres elementos se combinan en una cadena, que es la que se llama cadena base de firma
(signature base string) y será esta cadena la que se firme digitalmente. Así pues la cadena base
de firma incluye todo lo que es relevante de una petición http: su verbo, su URL y sus
parámetros.
El proceso de conseguir la cadena base de firma a partir de una petición de http se conoce
como normalización de peticiones. Y es que, como veremos ahora, peticiones distintas, pero
que signifiquen lo mismo, van a generar la misma cadena base de firma. ¿A que me refiero con
peticiones no idénticas pero que signifiquen lo mismo? Pues que tengan los mismos
parámetros pero en orden distinto, o que la URL sea igual pero difiera en mayúsculas o
minúsculas.

Creación de la cadena base de firma
Para obtener esta cadena a partir de una petición http, debemos realizar unos pasos sencillos,
pero de vital importancia (si nos equivocamos en esto, nuestra cadena base diferirá de la que
calcule el proveedor de servicios y por lo tanto la firma digital será distinta, generando una
petición inválida):
    1. Obtener el verbo http usado, en mayúsculas (p.ej. POST o GET).
    2. Obtener la URL normalizada. Esto significa que la URL se pasa toda a minúsculas. El
       valor del host y del port debe coincidir con el valor de la cabecera “Host”. La ruta hasta
       la query string se añade tal cual. El puerto se incluye solo si no es el estándar (80 para
       http o 443 para https).
    3. Obtener una cadena con todos los parámetros de la petición. Para ello con
       independencia de donde estén (query string, cuerpo de la petición o cabecera
       Authorization) se ordenan por orden alfabético y se concatenan uno tras otro
       (nombre=valor). Si dos parámetros tienen el mismo nombre, se ordenan por su valor.
       Si un parámetro está vacío, aparece igualmente sin valor.
    4. Se codifica la URL normalizada, siguiendo un procedimiento propio, llamado percent
       encoding.
    5. Se codifica la cadena con todos los parámetros de la URL, siguiendo el mismo
       procedimiento anterior
    6. Se crea una cadena con el valor de 1, el símbolo &, el valor de 4, el símbolo & y el valor
       de 5.

Esta cadena obtenida en el punto 6 es la cadena base de firma, y de la cual se calculará el hash
para obtener la firma digital de la petición.

El método de codificación percent encoding
Este método se usa solo para el cálculo de la cadena base de firma. Es un método muy
parecido y basado en el método de codificación de URIs (definido por la RFC 3986 en su
apartado 2.1). La RFC de OAuth 1.0, en su sección 3.6 define claramente como es esta
codificación:
    1. Se codifica la cadena en UTF8
2. Los siguientes caracteres: letras, números, “-“,”.”,”_” y “~” no son codificados y se
       ponen tal cual.
    3. Cualquier otro carácter debe ser codificado usando %xx, donde xx es el código
       hexadecimal, en mayúsculas, del byte.

Aunque el método parece idéntico al definido por el RFC 3986 en su apartado 2.1 no lo es. Hay
una sutil diferencia: en OAuth se codifican todos los caracteres excepto los indicados en el
punto 2. Mientras que en el RFC 3986 algunos caracteres no se codifican si actúan como
separadores. Es un detalle importante. P.ej. la URL http://www.krasis.com codificada según la
RFC 3986 es: http://www.krasis.com, mientras que usando el percent encoding de OAuth, los
caracteres “:” y “/” se codifican igualmente, aun cuando forman parte del separador :// que
separa protocolo de host. Así pues la URL queda como http%3ª%2F%2Fkrasis.com
Así pues cuidado con usar métodos que codifiquen URLs, incluso aunque sean conformes al
RFC 3986, ya que puede ser que no generen exactamente la misma cadena.


Elementos de una petición OAuth
Toda petición que llamemos petición OAuth deberá contener algunos elementos obligatorios
que son los parámetros OAuth y la firma digital. No todos los parámetros son obligatorios en
todo momento.
El protocolo define un conjunto de elementos que toda petición OAuth debe tener, y que
sirven para garantizar el buen funcionamiento de éste. Los que deben existir en toda petición
OAuth son:
    1.   El identificador del cliente (Consumer Key).
    2.   Un timestamp: Usualmente el número de segundos desde el 01 de Enero de 1970.
    3.   Un número único (nonce)
    4.   El método de firma digital usado
    5.   La firma digital

Luego, en algunas peticiones OAuth puede existir:

    6. El identificador temporal (Request Token)
    7. El identificador de acceso (OAuth Token)

De todos estos elementos el punto 3 merece especial atención, por lo ambiguo de su
definición. Realmente la especificación no dice mucho acerca de él, salvo que no tiene ni
porque ser un número y que su uso está recomendado para poder discernir entre dos
peticiones distintas dado un mismo timestamp. O sea que dos peticiones con el mismo
timestamp y del mismo cliente, deben tener un valor de nonce. La especificación no dice si
deben ser secuenciales o no, ¡de hecho ya hemos comentado que no tiene ni porque ser un
número! Cada proveedor puede establecer sus reglas y los clientes deben adaptarse a ellas. De
hecho su uso no es obligatorio, depende de cada proveedor de servicios.

Parámetros OAuth
El nombre de los distintos parámetros OAuth está definido por el protocolo y son los
siguientes:
1.   oauth_consumer_key: Identificador del cliente (Consumer Key)
    2.   oauth_timestamp: Timestamp de la petición
    3.   oauth_nonce: Valor del número único
    4.   oauth_signature_method: Contiene el tipo de método de firma digital que se usa.
    5.   oauth_signature: Contiene la firma digital de la petición
    6.   oauth_token: Contiene o bien el Request Token o bien el Access Token (en función del
         paso del flujo en el que nos encontremos).

Adicionalmente a estos parámetros existen otros que se usan en momentos puntuales y que
son los siguientes:

    7. oauth_callback: URL que debe llamar el autenticador con el código de verificación en
       el flujo 3-legged OAuth.
    8. oauth_token_secret: Credencial temporal privada / Access token privado (en función
       del paso del flujo en el que estemos) que nos devuelve el proveedor de servicios.
    9. oauth_verifier: Código de verificación que devuelve el autenticador

Al margen de esos se pueden definer parámetros adicionales y esos pueden empezar por
oauth_ si así se desea (la especificación no lo prohíbe).

Localización de los parámetros OAuth
Estos elementos se pueden incluir en distintas partes de la petición:
    1. En el querystring
    2. En el cuerpo de la petición (si el content type es application/form-www-urlencoded)
    3. En la cabecera Authorization, si esa indica que contiene datos OAuth. Esa es la manera
       recomendada por la especificación.
La especificación señala que un proveedor OAuth debe soportar los parámetros OAuth en
cualquier de esas partes de la petición y que debe vigilar que no haya elementos duplicados
(p.ej. un parámetro oauth_nonce en query string y otro en la cabecera Authorization). Si se
encuentran elementos duplicados debe devolverse un error, en lugar de usar uno de los dos en
función de cualquier posible criterio de prioridad.

Cabecera Authorization
Como se ha mencionado, la manera preferida es en la cabecera Authorization, según muestra
este ejemplo sacado de la propia RFC:

Authorization: OAuth realm="Photos",
oauth_consumer_key="dpf43f3p2l4k3l03",
oauth_signature_method="HMAC-SHA1", oauth_timestamp="137131200",
oauth_nonce="wIjqoS",
oauth_callback="http%3A%2F%2Fprinter.example.com%2Fready",
oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D"

La cabecera Authorization debe indicar que es de tipo OAuth y el parámetro realm de aparecer
se ignora a efectos de OAuth.
Como se puede ver el formato es nombre=”valor” (el valor está entrecomillado). Si un
parámetro tiene un valor vacío debe aparecer nombre=”” (dos comillas dobles seguidas).
Estríctamente hablando entre el nombre del parámetro y el signo de igual no se admiten
espacios. Al igual que entre el signo de igual y la primera de las dos comillas dobles. Los
parámetros van separados por una coma y un salto de línea opcional. Lo que es importante es
que el valor del parámetro está codificado usando Percent Encoding (ver el valor del
parámetro oauth_callback para un ejemplo).

En la RFC (apartado 3.5.1) se especifica con todo lujo de detalles el formato de la cabecera
Authorization.


Flujos de OAuth
Vamos a explorar los diversos flujos de OAuth que existen. La especificación en sí define un
solo flujo, el conocido como 3-legged OAuth, pero vamos a explorar algunos flujos más que se
pueden encontrar en distintos proveedores (como linkedin o twitter). Dos de ellos están
pensados para aplicaciones de escritorio (o móviles) otro es para el caso de que queramos
ejecutar servicios pero en nombre de ningún usuario en concreto y finalmente hablaremos
sobre la pseudo-autenticación usando OAuth (el famoso “sign with Facebook” que se ve en
numerosas web).
Esos flujos se diferencian tan solo por la forma en que el cliente (ya sea otra web o una
aplicación de escritorio) consigue los tokens OAuth definitivos). Empecemos por el flujo
definido por la propia especificación

3-legged OAuth
Este es el flujo más conocido de OAuth y por el cual realmente fue creado. En este caso se
asume que el cliente es capaz de tener un endpoint accesible para que el autenticador le
pueda enviar el código de verificación. Evidentemente esto solo es posible si el cliente es una
aplicación web. Pero vayamos paso a paso...
El primer paso es que el cliente realice una petición OAuth para pedir un par de tokens
temporales. Esos tokens temporales (conocidos comúnmente como request token and secret)
son los que usarán en todo el flujo hasta terminar obteniendo los tokens definitivos (conocidos
como access token and secret). Para obtener estos tokens el cliente básicamente se identifica
a si mismo (usando su consumer key) y envía un parámetro llamado oauth_callback que es a
donde debe recibir el código de validación que le servirá para obtener los tokens definitivos.
El proveedor de servicios responde a dicha petición con los tokens temporales contenidos en
los parámetros oauth_token y oauth_token_secret. ¡Todo el proceso ya se ha puesto en
marcha!
Ahora el cliente debe llamar al autenticador pasándole el Request Token que ha recibido. Esta
petición, como va contra el autenticador y no contra el proveedor de servicios no es una
petición OAuth. Es decir, el cliente no se identifica a sí mismo, ni la petición va firmada. El
autenticador comprueba que el token temporal es válido, mira cual fue el cliente que lo
solicitó (el proveedor de servicios debe haber guardado esta información en algún sitio
accesible para el autenticador) y entonces pueden suceder varias cosas:
1. Que el token temporal pasado no sea válido: Se muestra un mensaje de error al
       usuario.
    2. Que el token temporal sea válido y que el usuario NO esté autenticado contra el
       autenticador. El usuario recibirá el formulario de login del autenticador donde se le
       pedirán sus credenciales y que acepte dar permisos a la aplicación indicada. Si el
       usuario se autentica y da los permisos se sigue al punto 4.
    3. Que el token temporal sea válido y el usuario esté autenticado. Si el usuario NO había
       dado permisos a la aplicación indicada se le pedirá que le de esos permisos. Si el
       usuario ya los había dado se seguirá al punto 4.
    4. El autenticador redirige al usuario a la dirección de callback que especificó el cliente en
       la primera petición. La dirección de callback recibirá dos parámetros: el token
       temporal y un código de verificación.

¡Ya casi estamos! Una vez el cliente recibe en su dirección de callback una petición, junto con
un token temporal y un código de verificación debe:
    1. Asegurarse que el token temporal es el mismo que él ha generado
    2. Realizar una petición OAuth al proveedor de servicios mandándole el token temporal
       (Request Token) y el código de verificación. La respuesta a esta petición OAuth serán
       los tokens finales (Access token and secret) que se usan para identificar llamadas
       OAuth en nombre del cliente autenticado.

Cliente escritorio – Autenticación por PIN
Cuando el cliente es una aplicación de escritorio el proceso es un poco más pesado para el
usuario, ya que el cliente no puede especificar una dirección de callback. En este caso se usa lo
que se llama out-of-band configuration. El tema está en que la especificación lo menciona
explícitamente, pero luego no dice nada más acerca de este modo de configuración. Así que
este apartado está basado en cómo se ha implementado en Twitter. Este método es válido
para aplicaciones que pueden abrir una ventana de navegador (aunque no puedan
interaccionar con ella).
La primera petición es idéntica al flujo tradicional, salvo que el valor de oauth_callback debe
ser oob. Este valor está reconocido por la especificación para indicar que el cliente quiere usar
el método de configuración out-of-band. La respuesta del proveedor será, igual que antes, el
par de tokens temporales (Request Token y Request Secret).
La segunda petición del cliente será contra el autenticador. Puede ser que se use el mismo
endpoint que el caso anterior, o puede que no. Dependerá de cada implementación, aunque lo
normal es que se usen endpoints distintos del autenticador para poder personalizar el
comportamiento de éste en cada caso. El comportamiento del autenticador debe ser el mismo
que en el flujo anterior, aunque son posibles algunas variantes. P.ej. Twitter obliga a aceptar
de nuevo los permisos incluso aunque se hubiesen aceptado previamente para el mismo
cliente.
La principal diferencia con el flujo 3-legged es que una vez el usuario se autentica y da los
permisos a la aplicación, al no haber dirección de callback a la que redirigir el usuario, el
autenticador mostrará una página especial con un código (PIN) que el usuario deberá entrar a
la aplicación.
El usuario entra el código PIN a la aplicación, y la aplicación usa este código PIN como si fuese
el código de verificación: es decir, realiza una llamada OAuth al proveedor de servicios con el
Request Token, el PIN entrado por el usuario y obtiene los tokens OAuth definitivos.

Cliente escritorio – autenticación por password
Otro flujo posible para aplicaciones cliente que no pueden mostrar ni una ventana de
navegador, es mandarle al autenticador el login y password del usuario. Claro que eso implica
violar uno de los principios de OAuth: que el cliente nunca tiene acceso al login y password del
usuario. En este caso el usuario debe introducir su login y su password, pero solo una vez,
después la aplicación cliente no los usa nunca más, ya que el resto de peticiones son OAuth.
Por supuesto estamos ante un tema de confianza de la aplicación. Si yo me descargo la
aplicación oficial de Facebook, pongamos por caso, no tendré problemas en introducir mi login
y password en ella. Si me descargo una aplicación realizada por Hackers. Inc. Pues
seguramente no la entraré si me la pida (aunque la aplicación pueda ser legítima, yo no tengo
manera de saberlo).
Como siempre el primer paso del flujo es idéntico: una petición OAuth del cliente para obtener
los tokens temporales, mandando “oob” como valor de Oauth_callback.
Una vez tiene los tokens temporales, el cliente debe puede llamar al autenticador, pasándole
el Request Token junto con el login y el password del usuario. El autenticador comprueba las
credenciales y en caso de que sean correctas, responde con el código de verificación (debe
notarse que el autenticador asume que el usuario da permisos a la aplicación, cosa lógica
teniendo en cuenta que ha entrado su login y password en ella).
La aplicación una vez tiene el código de verificación, reanuda el flujo normal: manda el código
de verificación junto el token temporal al proveedor de servicios para obtener los tokens
definitivos. A partir de este punto todas las llamadas pueden ser OAuth y el login y password
del usuario se pueden descartar.

2-legged OAuth
Hay mucha confusión sobre que es 2-legged OAuth y existe básicamente porque es una forma
de usar OAuth que no se menciona nunca en la especificación, donde una aplicación autoriza a
otra aplicación a utilizar recursos protegidos, pero en este caso no se está involucrando a
ningún usuario. Todo el flujo de adquisición de tokens desaparece: si el cliente está registrado
en el proveedor (es decir tiene su par de claves) en lugar de usar el flujo normal y solicitar un
par de tokens temporales, lo que hace es:
    1. Realizar una llamada OAuth, usando su clave pública como Access Token (y firmando
       con el Client Secret).
El proveedor de servicios puede verificar que la clave pública pertenece a un cliente registrado
y conocido, puede verificar la firma y si esa es correcta ejecuta la petición. En este caso la
petición no se realiza en nombre de ningún usuario.

Pseudo-autenticación con OAuth
El flujo final que nos queda por ver es el de pseudo-autenticación, es decir cuando una web
permite autenticar a sus usuarios con las credenciales de un proveedor OAuth. Lo llamamos
pseudo-autenticación, porque a diferencia de un sistema de autenticación puro, como puede
ser OpenID, en el cual se pide la identidad del usuario, en el caso de OAuth se intenta acceder
a un recurso protegido en nombre de un usuario y el propio flujo de OAuth hará que el usuario
se autentique contra el proveedor de servicios. El cliente en este caso no sabe cuál es la
identidad del usuario, pero tiene un token OAuth a través del cual puede acceder a una API y
preguntar por su nombre.




Ilustración 2: Autenticación OpenID y pseudo-autenticación OAuth (fuente: Wikipedia)

Míralo de este modo: Si yo quiero saber quién eres tú, tengo dos modos de hacerlo:
    1. Pedirte que me muestres un documento que te autentique. Por supuesto ambos
       debemos acordar que tipos de documentos son válidos para autenticarte (el DNI es
       válido pero la tarjeta de la biblioteca, no).
    2. Pedirte las llaves de tu casa, entrar en ella contigo, abrir tu cartera y mirar tu DNI.
La primera sería una autenticación pura basada en un protocolo como OpenID. La segunda
sería pseudo-autenticación basada en OAuth. En el ejemplo del segundo punto, he puesto
contigo adrede, para que quede claro de que no puedo hacer lo que quiera cuando esté en tu
casa: tan solo puedo hacer lo que tú me hayas autorizado a hacer.
Realmente este flujo es idéntico a cualquiera de los tres flujos anteriores que hemos visto.
Todos los pasos son idénticos y la experiencia del usuario es la misma. La única diferencia está
en el cliente: antes el cliente solo quiere realizar una llamada a un servicio, mientras que ahora
si la llamada OAuth es exitosa, el cliente autentica al usuario dentro de su propio sistema. De
esta manera el usuario obtiene acceso a una determinada aplicación web usando sus
credenciales de otro proveedor OAuth (como pueda ser Facebook o Twitter). Para
desarrolladores de aplicaciones es muy interesante, porque no solo evitan que el usuario deba
darse de alta en su sistema, si no que además tienen acceso a los datos que el proveedor de
OAuth exponga de ellos (p.ej. podrían acceder al perfil de Facebook).

Mais conteúdo relacionado

Semelhante a Entendiendo o auth

Presentacion-Oauth
Presentacion-OauthPresentacion-Oauth
Presentacion-OauthKevin Medina
 
Analizando tus Redes Sociales con Power BI
Analizando tus Redes Sociales con Power BIAnalizando tus Redes Sociales con Power BI
Analizando tus Redes Sociales con Power BISolidQ
 
GFI - Seguridad en tus APIs
GFI - Seguridad en tus APIsGFI - Seguridad en tus APIs
GFI - Seguridad en tus APIsGFI Informática
 
Alejandro Castro_ Practica Shiderlshare.pdf
Alejandro Castro_ Practica Shiderlshare.pdfAlejandro Castro_ Practica Shiderlshare.pdf
Alejandro Castro_ Practica Shiderlshare.pdfHelderAlejandroCastr
 
Provisionamiento de un RAC de 2 nodos en la nube de Oracle.
Provisionamiento de un RAC de 2 nodos en la nube de Oracle.Provisionamiento de un RAC de 2 nodos en la nube de Oracle.
Provisionamiento de un RAC de 2 nodos en la nube de Oracle.Lorenzo Jose Mota Garcia
 
Desarrolo de un videojuego multijugador usando arquitectura Cliente-Servidor
Desarrolo de un videojuego multijugador usando arquitectura Cliente-ServidorDesarrolo de un videojuego multijugador usando arquitectura Cliente-Servidor
Desarrolo de un videojuego multijugador usando arquitectura Cliente-ServidorJhonatan Telmo Luis Visitacion
 
Servicios web
Servicios webServicios web
Servicios webjogoram
 
1 - Curso de Navegación Segura - Conceptos sobre navegadores
1 - Curso de Navegación Segura - Conceptos sobre navegadores1 - Curso de Navegación Segura - Conceptos sobre navegadores
1 - Curso de Navegación Segura - Conceptos sobre navegadoresJavier Navarro
 
Programación Web I - ISC - UCQ - Presentación 03
Programación Web I - ISC - UCQ - Presentación 03Programación Web I - ISC - UCQ - Presentación 03
Programación Web I - ISC - UCQ - Presentación 03Giovanni Orozco
 
El proceso de e commerce exposicion (1)
El proceso de e commerce exposicion (1)El proceso de e commerce exposicion (1)
El proceso de e commerce exposicion (1)Jairo Habeych
 
Elprocesodee commerceexposicion1-131127170703-phpapp01
Elprocesodee commerceexposicion1-131127170703-phpapp01Elprocesodee commerceexposicion1-131127170703-phpapp01
Elprocesodee commerceexposicion1-131127170703-phpapp01Edgar Yunes Oyaga
 
especificaciones de diseño de software para una página de viajes
especificaciones de diseño de software para una página de viajesespecificaciones de diseño de software para una página de viajes
especificaciones de diseño de software para una página de viajesGabriel Gongora
 
Servicios web
Servicios webServicios web
Servicios webmatiasreg
 
Servicios web
Servicios webServicios web
Servicios webmatiasreg
 
Web-alternativa-al-Senado-de-Espana-desarrollada-Open-Source
Web-alternativa-al-Senado-de-Espana-desarrollada-Open-SourceWeb-alternativa-al-Senado-de-Espana-desarrollada-Open-Source
Web-alternativa-al-Senado-de-Espana-desarrollada-Open-Sourcesenado-web-clon
 

Semelhante a Entendiendo o auth (20)

Presentacion-Oauth
Presentacion-OauthPresentacion-Oauth
Presentacion-Oauth
 
Oauth v2-rev
Oauth v2-revOauth v2-rev
Oauth v2-rev
 
Analizando tus Redes Sociales con Power BI
Analizando tus Redes Sociales con Power BIAnalizando tus Redes Sociales con Power BI
Analizando tus Redes Sociales con Power BI
 
GFI - Seguridad en tus APIs
GFI - Seguridad en tus APIsGFI - Seguridad en tus APIs
GFI - Seguridad en tus APIs
 
Alejandro Castro_ Practica Shiderlshare.pdf
Alejandro Castro_ Practica Shiderlshare.pdfAlejandro Castro_ Practica Shiderlshare.pdf
Alejandro Castro_ Practica Shiderlshare.pdf
 
Taller de arquitectura web
Taller de arquitectura webTaller de arquitectura web
Taller de arquitectura web
 
Provisionamiento de un RAC de 2 nodos en la nube de Oracle.
Provisionamiento de un RAC de 2 nodos en la nube de Oracle.Provisionamiento de un RAC de 2 nodos en la nube de Oracle.
Provisionamiento de un RAC de 2 nodos en la nube de Oracle.
 
Desarrolo de un videojuego multijugador usando arquitectura Cliente-Servidor
Desarrolo de un videojuego multijugador usando arquitectura Cliente-ServidorDesarrolo de un videojuego multijugador usando arquitectura Cliente-Servidor
Desarrolo de un videojuego multijugador usando arquitectura Cliente-Servidor
 
Uno
UnoUno
Uno
 
trabajo final de tic
trabajo final de tic trabajo final de tic
trabajo final de tic
 
Servicios web
Servicios webServicios web
Servicios web
 
OAuth and OpenID
OAuth and OpenIDOAuth and OpenID
OAuth and OpenID
 
1 - Curso de Navegación Segura - Conceptos sobre navegadores
1 - Curso de Navegación Segura - Conceptos sobre navegadores1 - Curso de Navegación Segura - Conceptos sobre navegadores
1 - Curso de Navegación Segura - Conceptos sobre navegadores
 
Programación Web I - ISC - UCQ - Presentación 03
Programación Web I - ISC - UCQ - Presentación 03Programación Web I - ISC - UCQ - Presentación 03
Programación Web I - ISC - UCQ - Presentación 03
 
El proceso de e commerce exposicion (1)
El proceso de e commerce exposicion (1)El proceso de e commerce exposicion (1)
El proceso de e commerce exposicion (1)
 
Elprocesodee commerceexposicion1-131127170703-phpapp01
Elprocesodee commerceexposicion1-131127170703-phpapp01Elprocesodee commerceexposicion1-131127170703-phpapp01
Elprocesodee commerceexposicion1-131127170703-phpapp01
 
especificaciones de diseño de software para una página de viajes
especificaciones de diseño de software para una página de viajesespecificaciones de diseño de software para una página de viajes
especificaciones de diseño de software para una página de viajes
 
Servicios web
Servicios webServicios web
Servicios web
 
Servicios web
Servicios webServicios web
Servicios web
 
Web-alternativa-al-Senado-de-Espana-desarrollada-Open-Source
Web-alternativa-al-Senado-de-Espana-desarrollada-Open-SourceWeb-alternativa-al-Senado-de-Espana-desarrollada-Open-Source
Web-alternativa-al-Senado-de-Espana-desarrollada-Open-Source
 

Mais de Eduard Tomàs

Kubernetes: Do's, don'ts and why's
Kubernetes: Do's, don'ts and why'sKubernetes: Do's, don'ts and why's
Kubernetes: Do's, don'ts and why'sEduard Tomàs
 
KCDS 2021- Escalando workloads serverless en Kubernetes con KEDA
KCDS 2021- Escalando workloads serverless en Kubernetes con KEDAKCDS 2021- Escalando workloads serverless en Kubernetes con KEDA
KCDS 2021- Escalando workloads serverless en Kubernetes con KEDAEduard Tomàs
 
Escalando workloads serverless en Kubernetes con Keda
Escalando workloads serverless en Kubernetes con KedaEscalando workloads serverless en Kubernetes con Keda
Escalando workloads serverless en Kubernetes con KedaEduard Tomàs
 
C#9 - Más C# que nunca
C#9 - Más C# que nuncaC#9 - Más C# que nunca
C#9 - Más C# que nuncaEduard Tomàs
 
CollabDays 2020 Barcelona - Serverless Kubernetes with KEDA
CollabDays 2020 Barcelona - Serverless Kubernetes with KEDACollabDays 2020 Barcelona - Serverless Kubernetes with KEDA
CollabDays 2020 Barcelona - Serverless Kubernetes with KEDAEduard Tomàs
 
Keda o como convertir Kubernetess en Serverless
Keda o como convertir Kubernetess en ServerlessKeda o como convertir Kubernetess en Serverless
Keda o como convertir Kubernetess en ServerlessEduard Tomàs
 
.NET Memoria y Rendimiento
.NET Memoria y Rendimiento.NET Memoria y Rendimiento
.NET Memoria y RendimientoEduard Tomàs
 
Containers en .NET (Dot Net 2018 - Spain)
Containers en .NET (Dot Net 2018 - Spain)Containers en .NET (Dot Net 2018 - Spain)
Containers en .NET (Dot Net 2018 - Spain)Eduard Tomàs
 
Esos contenedores, ¡a producción! (Commit Conf 2018)
Esos contenedores, ¡a producción! (Commit Conf 2018)Esos contenedores, ¡a producción! (Commit Conf 2018)
Esos contenedores, ¡a producción! (Commit Conf 2018)Eduard Tomàs
 
Codemotion 2015 - Bienvenido de nuevo c++
Codemotion 2015 - Bienvenido de nuevo c++Codemotion 2015 - Bienvenido de nuevo c++
Codemotion 2015 - Bienvenido de nuevo c++Eduard Tomàs
 
El "peor" lenguaje del mundo
El "peor" lenguaje del mundoEl "peor" lenguaje del mundo
El "peor" lenguaje del mundoEduard Tomàs
 
Containerize a netcore application with aks
 Containerize a netcore application with aks Containerize a netcore application with aks
Containerize a netcore application with aksEduard Tomàs
 
Escenarios avanzados en AKS (Global Azure Bootcamp Barcelona 2019)
Escenarios avanzados en AKS (Global Azure Bootcamp Barcelona 2019)Escenarios avanzados en AKS (Global Azure Bootcamp Barcelona 2019)
Escenarios avanzados en AKS (Global Azure Bootcamp Barcelona 2019)Eduard Tomàs
 
Aplicaciones de consola fáciles? Más quisieramos
Aplicaciones de consola fáciles? Más quisieramosAplicaciones de consola fáciles? Más quisieramos
Aplicaciones de consola fáciles? Más quisieramosEduard Tomàs
 
Serverless with Azure Functions and CosmosDb
Serverless with Azure Functions and CosmosDbServerless with Azure Functions and CosmosDb
Serverless with Azure Functions and CosmosDbEduard Tomàs
 
Docker y todo eso... más o menos
Docker y todo eso... más o menosDocker y todo eso... más o menos
Docker y todo eso... más o menosEduard Tomàs
 
Microservices: Yes or not?
Microservices: Yes or not?Microservices: Yes or not?
Microservices: Yes or not?Eduard Tomàs
 
React native - Unleash the power of your device
React native - Unleash the power of your deviceReact native - Unleash the power of your device
React native - Unleash the power of your deviceEduard Tomàs
 

Mais de Eduard Tomàs (20)

Kubernetes: Do's, don'ts and why's
Kubernetes: Do's, don'ts and why'sKubernetes: Do's, don'ts and why's
Kubernetes: Do's, don'ts and why's
 
KCDS 2021- Escalando workloads serverless en Kubernetes con KEDA
KCDS 2021- Escalando workloads serverless en Kubernetes con KEDAKCDS 2021- Escalando workloads serverless en Kubernetes con KEDA
KCDS 2021- Escalando workloads serverless en Kubernetes con KEDA
 
Escalando workloads serverless en Kubernetes con Keda
Escalando workloads serverless en Kubernetes con KedaEscalando workloads serverless en Kubernetes con Keda
Escalando workloads serverless en Kubernetes con Keda
 
C#9 - Más C# que nunca
C#9 - Más C# que nuncaC#9 - Más C# que nunca
C#9 - Más C# que nunca
 
CollabDays 2020 Barcelona - Serverless Kubernetes with KEDA
CollabDays 2020 Barcelona - Serverless Kubernetes with KEDACollabDays 2020 Barcelona - Serverless Kubernetes with KEDA
CollabDays 2020 Barcelona - Serverless Kubernetes with KEDA
 
Keda o como convertir Kubernetess en Serverless
Keda o como convertir Kubernetess en ServerlessKeda o como convertir Kubernetess en Serverless
Keda o como convertir Kubernetess en Serverless
 
.NET Memoria y Rendimiento
.NET Memoria y Rendimiento.NET Memoria y Rendimiento
.NET Memoria y Rendimiento
 
Containers en .NET (Dot Net 2018 - Spain)
Containers en .NET (Dot Net 2018 - Spain)Containers en .NET (Dot Net 2018 - Spain)
Containers en .NET (Dot Net 2018 - Spain)
 
Esos contenedores, ¡a producción! (Commit Conf 2018)
Esos contenedores, ¡a producción! (Commit Conf 2018)Esos contenedores, ¡a producción! (Commit Conf 2018)
Esos contenedores, ¡a producción! (Commit Conf 2018)
 
Codemotion 2015 - Bienvenido de nuevo c++
Codemotion 2015 - Bienvenido de nuevo c++Codemotion 2015 - Bienvenido de nuevo c++
Codemotion 2015 - Bienvenido de nuevo c++
 
El "peor" lenguaje del mundo
El "peor" lenguaje del mundoEl "peor" lenguaje del mundo
El "peor" lenguaje del mundo
 
Containerize a netcore application with aks
 Containerize a netcore application with aks Containerize a netcore application with aks
Containerize a netcore application with aks
 
Escenarios avanzados en AKS (Global Azure Bootcamp Barcelona 2019)
Escenarios avanzados en AKS (Global Azure Bootcamp Barcelona 2019)Escenarios avanzados en AKS (Global Azure Bootcamp Barcelona 2019)
Escenarios avanzados en AKS (Global Azure Bootcamp Barcelona 2019)
 
Aplicaciones de consola fáciles? Más quisieramos
Aplicaciones de consola fáciles? Más quisieramosAplicaciones de consola fáciles? Más quisieramos
Aplicaciones de consola fáciles? Más quisieramos
 
Serverless with Azure Functions and CosmosDb
Serverless with Azure Functions and CosmosDbServerless with Azure Functions and CosmosDb
Serverless with Azure Functions and CosmosDb
 
Docker y todo eso... más o menos
Docker y todo eso... más o menosDocker y todo eso... más o menos
Docker y todo eso... más o menos
 
Microservices: Yes or not?
Microservices: Yes or not?Microservices: Yes or not?
Microservices: Yes or not?
 
ASP.NET MVC Core
ASP.NET MVC CoreASP.NET MVC Core
ASP.NET MVC Core
 
Azure functions
Azure functionsAzure functions
Azure functions
 
React native - Unleash the power of your device
React native - Unleash the power of your deviceReact native - Unleash the power of your device
React native - Unleash the power of your device
 

Entendiendo o auth

  • 1. Entendiendo oAuth Una breve explicación sobre oAuth 1.0 Eduard Tomàs (@eiximenis en twitter) 4/28/2012 Este documento es una breve introducción a oAuth, comentando brevemente como funciona el procolo en su versión 1.0a y mencionando los distintos flujos de oAuth existentes
  • 2. Entendiendo OAuth Contenido ¿Qué es OAuth? ........................................................................................................................ 2 La necesidad de OAuth .......................................................................................................... 2 Tokens, tokens, tokens.............................................................................................................. 3 Criptografía para dummies.................................................................................................... 3 Dos amigos... ..................................................................................................................... 4 ...y el novio celoso. ............................................................................................................ 5 Firmas digitales ................................................................................................................. 6 Firma de peticiones en OAuth ............................................................................................... 8 Tipo de tokens OAuth ........................................................................................................ 9 Normalización de peticiones ........................................................................................... 11 Creación de la cadena base de firma ............................................................................... 12 El método de codificación percent encoding .................................................................... 12 Elementos de una petición OAuth ........................................................................................... 13 Parámetros OAuth .............................................................................................................. 13 Localización de los parámetros OAuth ................................................................................. 14 Cabecera Authorization ................................................................................................... 14 Flujos de OAuth ...................................................................................................................... 15 3-legged OAuth ................................................................................................................... 15 Cliente escritorio – Autenticación por PIN ........................................................................... 16 Cliente escritorio – autenticación por password .................................................................. 17 2-legged OAuth ................................................................................................................... 17 Pseudo-autenticación con OAuth ........................................................................................ 17 Desde ya hace un tiempo se oye hablar mucho de OAuth. Casi cualquier red social o aplicación web que exponga una API pública para desarrolladores expone sus servicios usando este protocolo. ¿Quieres integrarte con Twitter, Linkedin, Facebook o Google+, entre muchas otras? Todas ellas requieren usar OAuth para poder utilizar sus servicios. El objetivo de este documento no es que puedas aprender a crear un cliente que use OAuth, para ello no hay mejores tutoriales que los propios que desarrollan los creadores de servicios (créeme: ellos son los primeros interesados en que uses sus servicios). Tampoco es objetivo de este documento explicar todos los pormenores de OAuth (para ello hay una especificación
  • 3. oficial). Entonces... ¿cuál es el objetivo? Pues simple y llanamente: que entiendas OAuth. Que entiendas qué es OAuth, cuál es su motivación, que problemas permite solucionar y que otros puede llegar a plantear. Por supuesto vamos a entrar en detalles sobre el funcionamiento de OAuth, aunque para descripciones detalladas referenciaremos a la RFC. Y sí, también veremos cómo crear un cliente OAuth y por encima de todo un proveedor de OAuth y cómo integrarlo en nuestras aplicaciones web usando, en este caso, ASP.NET MVC. Si te interesa el tema, y quieres conocer OAuth en lugar de simplemente usarlo... este documento es para ti. ¿Qué es OAuth? Resumiendo, OAuth es un protocolo de autorización (su nombre proviene de Open Authorization), que permite a un usuario (propietario de ciertos recursos) autorizar a un tercero a que acceda a dichos recursos en su nombre pero sin darle en ningún momento a este tercero sus credenciales de autenticación (es decir, sin darle a este tercero su nombre de usuario ni contraseña). Actualmente está en su versión 1.0a y se está desarrollando la versión 2.0 que va a ser incompatible con la versión anterior. Dicha versión 2.0 debería haberse finalizado a finales del 2011, pero sigue estando todavía en desarrollo y sin fecha prevista de finalización. La principal mejoras de OAuth 2.0 respecto a 1.0a son que es más fácil de usar para el usuario. Este documento se basa en OAuth 1.0. Aun cuando OAuth es un protocolo de autorización es posible conseguir una pseudo autenticación con él, y de hecho uno de usos más extendidos es el de entrar en una aplicación web usando el usuario y contraseña de otra aplicación. De esta manera grandes proveedores de OAuth, como Facebook, se convierten a su vez en proveedores de autenticación de otras webs. Así, paradójicamente, OAuth está teniendo éxito donde otros protocolos más orientados a autenticación como OpenID o anteriormente Passport (actual Live ID) no han terminado de tenerlo. Esto nos demuestra una vez más, que el éxito de un producto (un protocolo en este caso) viene muchas veces marcado por quien lo adopta, y el momento en que lo adopta, más que en las características técnicas de éste. Esta es una lección que solemos olvidar demasiado a menudo. La necesidad de OAuth La necesidad de un protocolo de autorización como es OAuth suele ser la confianza. O mejor dicho, la falta de ella. El hecho de que yo como usuario no confíe en una aplicación lo suficiente como para darle mis datos de autenticación pero por otro lado quiera permitir que dicha aplicación realice algo en mi nombre. Y no es lo mismo realizar algo en el nombre de alguien, que suplantar a este alguien. Esto es precisamente lo que permite OAuth: que alguien realice tareas en nombre de otro, pero sin poder suplantarlo: en todo momento se sabe quién es realmente el que está realizando las tareas. Al tener la autorización separada de la autenticación, yo puedo en cualquier momento desautorizar a quien yo haya autorizado previamente. Es decir, impedir que siga realizando tareas en mi nombre. Y puedo hacer esto sin necesidad de modificar mi usuario o contraseña.
  • 4. Y desde el punto de un proveedor de servicios... ¿Qué le ofrece OAuth que motive el usarlo? Pues precisamente el hecho de querer generar un ecosistema de terceros que usen sus servicios. Pongamos como ejemplo a Facebook. Facebook no expone su API para su propia aplicación móvil, la expone básicamente para permitir todo un desarrollo de un ecosistema de aplicaciones integradas en Facebook, pero realizadas por otros. Es una relación win-win entre Facebook y el creador de la aplicación. El segundo puede aprovechar todo el potencial social que Facebook puede generar, y el primero obtiene más interacciones que es lo que más necesita una red social. Por supuesto que todo esto se podría conseguir sin OAuth, pero en unos tiempos donde se están mandando tantos (acertados) mensajes contra el phising y continuamente se nos dice que vigilemos nuestras credenciales y que no nos fiemos, no quedaría muy bien que cualquier web o aplicación nos pidiese el usuario y contraseña de Facebook... ¿Qué hará con ellos? ¿Cómo tengo yo la seguridad, como usuario, de que la aplicación es bienintencionada? Además, incluso en el caso de que la aplicación fuese bienintencionada, el que todas mis aplicaciones conectadas a Facebook tengan mi usuario y contraseña implica que si alguna vez, por cualquier razón, los modifico deba informar a todas esas aplicaciones de nuevo. Como veremos más adelante OAuth me permite obviar todo esto. Así pues, OAuth expone claras ventajas tanto para usuarios como para desarrolladores de servicios. Ha llegado el momento de ver, someramente, como funciona. Tokens, tokens, tokens La verdad es que OAuth va, básicamente, sobre intercambiar tokens. Hay tres roles que debemos considerar:  El cliente, que quiere acceder a un servicio en nombre de un usuario. Este cliente puede ser una aplicación web, móvil o de escritorio.  El proveedor de servicios, que provee el servicio al cual quiere acceder el cliente  El autenticador que autentica los usuarios Lo que OAuth define es como esos tres roles deben comunicarse entre ellos para que al final el cliente pueda acceder al servicio. Lo que no define OAuth es como el autenticador realiza su trabajo (es decir, como se autentica el usuario). El objetivo final es que el cliente consiga lo que desde siempre se ha llamado Access token (aunque en la RFC decidieron modificar todos los nombres y lo llamaron Token Credentials). Enviando este token el cliente puede acceder a un recurso protegido en nombre del usuario que haya autenticado el autenticador. Criptografía para dummies Antes de meternos de lleno en OAuth, dado que vamos a hablar de firma digital y métodos criptográficos de clave simétrica o asimétrica déjame que te hable un poco sobre conceptos elementales de criptografía. Si conoces que son los métodos de clave simétrica, asimétrica y la firma digital, eres libre de saltarte este apartado :) Y por supuesto, si encuentras todo el tema de la criptografía aburrido y falto de interés te lo puedes saltar también, en el fondo no es necesario conocerlo para poder usar OAuth... Aunque sí para entenderlo realmente, y como de eso se trata, si te apetece… ¡allá vamos!
  • 5. Dos amigos... Imaginemos a dos amigos, Alice y Bob que quieren enviarse un mensaje codificado sin que nadie más pueda descifrarlo. Hay muchos mecanismos de encriptación que pueden utilizar, pero los podemos dividir en dos grupos: de clave simétrica y de clave asimétrica. Los de clave simétrica son los primeros que nos vienen a la cabeza cuando pensamos en mecanismos de codificación. Tenemos una función (f) que dada una clave (K) y un texto a codificar (t) devuelve el texto codificado (t’). Entonces se cumple que:  ( , )=  ( , )= Es decir, para cifrar y descifrar se usa la misma clave. Ahora supongamos que Alice y Bob quieren mantener una conversación privada y para ello deciden cifrarla. Lo primero que tienen que hacer es quedar de acuerdo en la clave a usar. Bastaría con un correo de Alice proponiendo la clave y uno de Bob aceptándola. A partir de este punto ambos usan la misma clave y la conversación puede tener lugar. Si has arrugado la nariz cuando he mencionado que Alice envíe un correo con la clave es que has visto el punto débil de los métodos de clave simétrica: el intercambio de la clave. Es un punto muy delicado, ya que si alguien (un tal Mallory que os presentaré luego) descubre la clave, toda la conversación entre Alice y Bob está comprometida. Es aquí donde entran en juego los mecanismos de clave asimétrica. Dichos mecanismos se basan en algo muy simple (pero a la vez muy potente): la capacidad de generar dos pares de claves, ligadas de algún modo entre sí, de forma que al codificar algo con una de las claves se pueda decodificar con la otra y viceversa. Así pues si tenemos un par de claves, llamémoslas A y B, un texto (t) a codificar y una función (f) que dado una clave y un texto devuelve un texto codificado, se cumple que:  , ( , ) = , ( , ) = Y no sólo eso, si no que la relación NO es reflexiva:  , ( , ) <>  , ( , ) <> Cada uno de ellos por separado y sin comunicárselo a nadie genera un par de claves (A,B). En este momento Alice tiene su par de claves y Bob las suyas. Posteriormente ambos se envían por mail una sola de esas claves (pongamos la A), a la que llamaremos la clave pública. La otra clave del par de claves, se la guardan para ellos mismos y no la dicen a nadie así que la llamaremos la clave privada. De hecho, cualquiera que más adelante quisiera enviar mensajes a Bob, como su amigo del instituto Charlie, debe pedirle a Bob que le dé la clave pública. Tan solo esa. En este momento, Bob pondría enviar un mensaje a Alice, encriptado con la clave pública de ella. El resultado es un mensaje que solo puede decodificar quien posea la otra clave del par de claves. Y dado que Bob ha usado la clave pública de Alice, quien posee la otra clave del par de claves es la propia Alice: se trata de su clave privada. De este modo Bob ha conseguido
  • 6. enviar un mensaje que solo Alice puede entender. ¿Y si ahora Alice quiere responder el mensaje? Pues muy simple: tan solo debe cifrarlo usando la clave pública de Bob, para que este al recibirlo use su clave privada y pueda descifrarlo. Resumiendo, la idea es muy simple: se cifra el mensaje con la clave pública del receptor, el cual debe usar su clave privada (que solo conoce él) para descifrarlo. Este sistema asegura cifrado y descifrado seguro de los mensajes (tan seguro como sea el algoritmo de encriptación que se use, pero eso es otra historia). Pero existe un riesgo que debemos tener presente. ...y el novio celoso. ¿Recordáis que antes mencionamos a Mallory? Dejadme que os lo presente: es el novio de Alice. Aunque es un buen tipo, es extremadamente celoso y como cree que Bob tiene intenciones poco honestas con Alice hace tiempo que está espiando lo que ella hace. En el fondo Mallory no le tiene manía a Bob: cree que todo el mundo quiere algo con Alice más allá de la amistad. A priori puede parecer que el mecanismo de encriptación basado en clave asimétrica les protege del todo: la única clave que circula al principio de la conversación entre Alice y Bob es la clave pública de cada uno de ellos que solo sirve para cifrar, nunca para descifrar, así que aunque Mallory supiese la clave pública no podría hacer nada (a diferencia de un mecanismo de clave simétrica, ya que en este caso si Mallory descubre la clave puede descifrar toda la conversación). En efecto, es cierto que si Mallory tan solo conoce las claves públicas de ambos no puede comprometer la seguridad de la comunicación de los dos amigos... Pero esta certeza no es garantía de una seguridad absoluta. Y es que Mallory instaló un proxy conectado a su propio ordenador que le permite tener acceso e interceptar todo lo que su novia envía y recibe desde internet (sí, los celos son muy malos). Gracias a esto Mallory intercepta el correo en el que Alice le pedía a Bob su clave pública y deja que llegue a Bob. Bob recibe el mensaje que proviene de Alice y le contesta con su clave pública. Dicho mensaje es interceptado de nuevo por Mallory, quien cambia la clave pública de Bob por la suya, se guarda la clave pública de Bob y reenvía el mensaje a Alice. En este punto Alice cree tener la clave pública de Bob, pero realmente tiene la de su novio. Así cuando Alice quiere decirle algo a Bob, lo encripta con la clave pública de este... o con lo que ella cree que es la clave pública de Bob. Porque realmente es la de Mallory, el cual puede descifrarlo (usando su clave privada), modificarlo, cifrarlo de nuevo (usando la clave pública de Bob que se ha guardado antes) y reenviar el mensaje a Bob, quien creerá que el mensaje proviene de Alice. Este tipo de ataques, en el cual un tercero (Mallory) puede interceptar, leer y modificar mensajes que se envían un par de actores (Alice y Bob) sin que ninguno de ellos pueda saber que su seguridad ha sido comprometida se llaman ataques Man-in-the-Middle. El error de Bob y Alice ha sido permitir que Mallory interceptara un único mensaje: el que usaron para intercambiar sus claves. Este es el punto débil de todo sistema de criptografía: el intercambio de claves (sí, incluso en los asimétricos donde podríamos creer que evitaban este problema).
  • 7. Amigo lector, por si lo has pensado, una solución muy rápida que evitaría los trapicheos de Mallory, sería evitar que hubiese intercambio de claves públicas al inicio de la conversación entre Bob y Alice. Si ambos publicasen su clave pública en una web, a la vista del todo el mundo, Mallory no podría interceptar ningún mensaje y sustituir las claves porque este mensaje no existiría: cuando Alice quisiera ver la clave pública de Bob la miraría en esta web y viceversa. Claro que en este caso tanto Alice como Bob deben tener estar seguros de que la web donde publican sus claves públicas es de confianza. No vaya a ser que le encarguen hacer la web a Chuck, un antiguo compañero de fiestas de Mallory, con lo que estarían igual que antes. Pero si la web es de una empresa que ofrece este servicio (hospedar claves públicas), y que ofrece absolutas garantías de seguridad, entonces sí que Mallory no tiene nada que hacer y Alice y Bob pueden estar tranquilos... Y aunque pueda parecer muy tonto, esto de publicar las claves públicas de todos en un sitio común, es más o menos lo que hacemos actualmente con los certificados digitales y las infrastructuras de clave pública (PKI). Firmas digitales Si has entendido como funciona la encriptación, ya estás listo para comprender como funciona la firma digital. El concepto de firma digital es extremadamente sencillo: se trata de aplicar una función de hash al documento y cifrar tan solo el hash. El hash cifrado constituye la firma digital. Funciones de hash Si Bob quiere enviar un documento firmado digitalmente, debe calcular el hash de este documento. El hash no es más que aplicar una función que devuelva un valor resumen que dependa de los datos del documento. Lo de resumen viene porque generalmente el tamaño en bytes del documento suele ser superior al tamaño en bytes del hash. Así una posible función de hash sería sumar los códigos ASCII de todos los caracteres del documento y realizar el módulo 256. Con esto obtendríamos un número de 0 a 255. Fijaos que convertimos textos de cualquier número de byes a valores de un solo byte, de ahí lo de resumen. Dada esa función de hash, el hash del texto Hola seria 132. Por supuesto esta es una función de hash horrorosa, seguro que no te cuesta nada encontrar otro texto distinto que dé el mismo valor de hash. Es evidente que, por norma general, siempre habrá más documentos que hash posibles (en nuestro caso hay infinitos documentos posibles y tan solo 256 hash), por lo que habrá colisiones (es decir dos documentos distintos que generen el mismo hash). Lo que distingue una buena función de hash de una de mala es lo que cueste encontrar dos documentos distintos que generen un mismo hash (lo que en criptografía se conoce como resistencia a las colisiones y que mide cuan resistente es una función de hash frente a lo que se conoce como un ataque de cumpleaños). Suponiendo una función de hash con alta resistencia a las colisiones (es decir que sea inviable encontrar dos elementos que den el mismo hash) entonces Bob puede firmar un documento de la siguiente manera: 1. Calcula el hash del documento 2. Cifra el hash y obtiene la firma digital. 3. Envía el documento junto con la firma digital.
  • 8. Lo importante aquí es que el documento no tiene por qué estar encriptado (puede estarlo pero no es obligatorio). Lo que está cifrado usando la clave privada de Bob es el hash y eso constituye la firma digital. Cuando el receptor reciba el documento debe: 1. Descifrar la firma digital para obtener el hash 2. Calcular por su parte el hash del documento (usando la misma función de hash) 3. Comparar ambos valores (el hash descifrado y el hash calculado) Si ambos valores coinciden la firma digital del documento es válida… ¿y qué significa exactamente esto? Pues depende del mecanismo de cifrado que se use para cifrar el hash. Firmas con mecanismos asimétricos vs firmas con mecanismos simétricos A grandes rasgos: una firma digital correcta indica que el documento no ha sido modificado por nadie a excepción de un remitente válido y que ha sido enviado por un remitente válido. Lo que significa exactamente “remitente válido” varía en función de si para cifrar el hash se usó un mecanismo con claves simétricas o asimétricas. Si se ha usado un mecanismo con claves asimétricas, remitente válido es aquel que ha enviado el documento. Nadie más. Debe notarse que decimos aquel que ha enviado el documento, no aquel que legítimamente puede leerlo. Si en el ejemplo anterior Bob hubiese usado un mecanismo de cifrado asimétrico podemos afirmar que el documento no ha sido alterado (lo que se ha recibido es lo que se ha enviado) por nadie más. No solo eso, si no que además se puede asegurar que ha sido Bob quien lo ha enviado (o dicho a la inversa, Bob no puede negar haber enviado el documento, lo que se conoce como no repudio). Si alguien intercepta el documento y lo modifica, dado que no puede modificar la firma digital (ya que está cifrada con la clave privada de Bob que tan solo tiene él), cuando el receptor reciba el mensaje el hash que él calcule diferirá del que venía con el documento, con lo que se sabrá que ha sido interceptado y modificado. Si se ha usado un mecanismo de clave pública, entonces “remitente válido” significa cualquiera que conozca la clave. Es decir cualquiera que pueda recibir un mensaje y calcular la firma digital. Si Bob calcula su firma digital cifrando el hash con un mecanismo de clave simétrica, es evidente que Alice debe conocer la clave para poder descifrar el hash y compararlo con el que obtenga ella para validar la firma digital. Pero dado que la clave que se usa para descifrar es la misma para cifrar y que Alice también la tiene, nada impide que Alice modifique el documento, vuelva a calcular el hash y lo cifre de nuevo usando la misma clave. En este caso no podemos pues asegurar unívocamente como antes que lo ha enviado Bob. Puede haberlo enviado Alice. No hay manera de saberlo. La firma digital sigue asegurando, eso sí, que si el mensaje es modificado por alguien que no conoce la clave de cifrado, el resto de participantes que sí la tienen se darán cuenta de que el mensaje ha sido modificado. Digamos que, usando un mecanismo cifrado de clave simétrica, todos los participantes válidos son tratados como una misma persona. Seguridad de la firma digital Fíjate que la asunción principal que se realiza de la firma digital (se puede asegurar que el documento no ha sido modificado), depende directamente de que la función de hash tenga una alta resistencia a las colisiones. De hecho lo que debe evitarse es que sea factible para alguien generar un par de documentos (uno auténtico y otro fraudulento) que tengan el
  • 9. mismo hash1. Si eso es factible (a nivel computacional) de realizar, alguien, llamémosla Carol, podría presentar el documento auténtico a Bob, quien lo firmaría y luego podría añadir la firma digital de Bob al documento fraudulento, con lo que a todos los efectos sería como si Bob hubiese firmado dicho documento falso. El propósito de la firma digital no es evitar que alguien intercepte el mensaje, si no asegurar que éste no ha sido alterado en tránsito y que es enviado realmente por el remitente. Si se quiere evitar que el mensaje sea visible a terceros, este debe además cifrarse. Eso sí, que quede claro: La firma digital no evita que pueda existir un Man-in-the-middle si el intercambio de claves ha sido comprometido. OAuth permite usar tanto mecanismos de clave simétrica como mecanismos de clave simétrica para cifrar el hash y obtener la firma digital. A la práctica la mayoría de proveedores soportan tan solo un mecanismo de clave simétrico (HMAC) para evitar todo el proceso de negociación de claves públicas. Aunque es un poco menos seguro (cualquiera que robe la clave que se use para cifrar los mensajes podrá enviar mensajes OAuth válidos) evita todo el trasiego de intercambio de claves públicas. Firma de peticiones en OAuth En OAuth todas las peticiones que realiza el cliente van firmadas digitalmente. La especificación habla explícitamente de tres métodos de firmado: 1. HMAC-SHA1: Que es un método de firma electrónica basado en la función de hash SHA1 y el método de cifrado simétrico HMAC 2. RSA-SHA1: Que es un método de firma electrónica basado en la función de hash SHA1 y el método de cifrado asimétrico RSA. La especificación no dice nada sobre como el cliente y el proveedor de servicios intercambian sus claves públicas. 3. PLAINTEXT: No existe firma digital. El valor de la firma digital se sustituye por el valor de los tokens secretos (Consumer Secret, Request Secret y Access Secre) que se usen en cada momento. Este método es altamente inseguro y de hecho la propia especificación ya indica que debe usarse sobre un canal de comunicación seguro (SSL o TLS) y tiene su razón de existir en que si se usa uno de esos canales, no es necesario añadir un método adicional como la firma electrónica para garantizar que la petición no ha sido modificada, dado que el propio canal seguro te lo asegura. Honestamente, en la especificación no queda muy claro si debe darse soporte a esos tres métodos o bien puede darse soporte a solo algunos de ellos. Lo que sí dice es que pueden añadirse métodos adicionales. En la vida real, hay muchos proveedores de OAuth que no soportan RSA-SHA1 supongo que para evitar el problema de intercambio de claves públicas, algo que se evita en HMAC-SHA1 al ser este un método asimétrico donde hay una sola clave compartida y conocida por todos. Personalmente creo que implementar solo HMAC-SHA1 es una solución más que válida- 1 Esto es importante: no es peligroso que varios documentos tengan el mismo hash (esto es inevitable, de hecho). Lo que es peligroso es que sea factible computacionalmente para alguien generar pares de documentos con el mismo hash.
  • 10. La necesidad de que en OAuth cada petición vaya firmada es, evidentemente, por seguridad: si no fuese así, alguien podría interceptar la petición del cliente al proveedor de servicios, modificarla y reenviarla de nuevo. Precisamente para evitar esto y asegurar que el proveedor de servicios solo responde a peticiones legítimamente enviadas por un cliente, estas deben ir firmadas. Esto no evita que alguien pueda ver los datos que se envían entre cliente y proveedor pero sí evita que puedan ser modificados. Es importante destacar que la respuesta del proveedor de servicios no va firmada (esto es así debido a la naturaleza síncrona de http): tan solo se firman las peticiones del cliente. Exacto: alguien con un sniffer podría modificar las respuestas del proveedor de servicios y el cliente no se daría cuenta, pero para evitar este escenario ya hay otras alternativas de seguridad adicionales a OAuth (SSL o TLS sin ir más lejos). Este no es un escenario que intente resolver OAuth. Quede claro pues que OAuth no es un protocolo de seguridad, ni quiere, ni puede, garantizar la seguridad o integridad de los datos enviados o recibidos. Cuando empieces a leer sobre OAuth, verás que continuamente se habla de pares de tokens: el token público y el secreto (key y secret en inglés). No te confundas: esos pares de tokens, ¡no son pares de claves asimétricas! Realmente uno de ellos (el público) actúa como identificador y el otro (el secreto) es el que se usa para firmar digitalmente. Tipo de tokens OAuth Consumer Key y Consumer Secret Por lo tanto todo cliente que quiera usar OAuth deberá tener su par de tokens. Quien otorga estos tokens y como estas son transferidas al cliente está fuera de la especificación de OAuth. Es decir, OAuth no define ningún mecanismo para que el cliente obtenga su par de tokens. Simplemente se asume que las tiene, y que ambos tanto cliente como proveedor de servicios las conocen. En terminología OAuth llamamos Consumer Key al token que identifica un cliente y Consumer Secret al token privado que este cliente usará para firmar sus peticiones OAuth. Aunque desde siempre se han llamado así, en la RFC decidieron modificar el nombre y llamarlos Client Credentials (credenciales de cliente) nombre que realmente es más acertado. La especificación no dice nada acerca de como el cliente obtiene sus credenciales, pero en la práctica lo más normal es tener que registrar el cliente manualmente, en el proveedor de servicios.
  • 11. Ilustración 1: Registro de una aplicación cliente en Twitter La Ilustración 1 muestra el proceso de registro de un cliente en Twitter. Una vez registrado el cliente Twitter nos informará de nuestras credenciales de cliente, que son las que deberemos usar. Este método es sencillo y eficaz aunque obliga a registrar cada posible cliente de forma manual. Tanto Facebook, como LinkedIn como cualquiera de los proveedores de OAuth ofrecen un mecanismo similar para el registro de clientes. Request Token y Request Secret El objetivo final de OAuth es permitir acceder a recursos protegidos en nombre de un usuario en concreto. Para ello, el cliente debe a partir de sus credenciales de cliente, obtener unos tokens finales que representen que el usuario ha dado permisos para acceder a esos recursos. Para ello el primer paso es obtener un par de tokens temporales, que servirán para ir enlazando toda la serie de peticiones OAuth que son necesarias para obtener los tokens definitivas (mucha gente se refiere a esa serie de peticiones con el nombre de OAuth Tokens dance).
  • 12. El Request Token identifica a una petición de permisos para un usuario en concreto. Cuando el cliente quiere obtener un token de acceso definitivo, lo que obtiene primero es el Request Token. Luego manda este Request Token al autenticador, quien (si el usuario acepta los permisos) le devuelve un código de verificación que luego el cliente puede usar para obtener los tokens finales (no te preocupes si eso te parece muy lioso ahora, luego aclararemos completamente el flujo OAuth). Lo importante es que te quedes con la idea de que el Request Token y el Request Secret son tokens temporales, que son descartados una vez se obtienen los definitivos. A lo mejor te estás preguntando por que es necesario un Request Secret. ¿No se supone que las peticiones van firmadas usando el Consumer Secret como clave para generar la firma digital? La respuesta es que una vez tenemos Request Token, las peticiones OAuth que hagamos irán firmadas usando el Consumer Secret y el Request Secret (ambos a la vez). ¡Ah sí! Se me olvidaba: He usado los nombres Request Token y Request Secret que son los que se usan comúnmente, pero la RFC usa otros nombres que son (de nuevo) mucho más acertados: Temporary Credentials. Access Token y Access Secret El Access Token y el Access Secret (llamados en la RFC Token Credentials) son el objetivo final: los tokens que se obtienen una vez el usuario se ha validado y ha aceptado los permisos demandados por el cliente. Una vez el cliente obtiene esos tokens, el flujo de OAuth termina y el cliente puede empezar a realizar llamadas al proveedor de servicios en nombre del usuario. El Access Secret se usa para firmar todas las peticiones OAuth que haga el cliente una vez tenga el Access Token (se usa conjuntamente con el Consumer Secret). Ahora que ya conoces los tres pares de tokens de OAuth... viene la pregunta clave: ¿qué datos de la petición se firman? Normalización de peticiones La firma digital de un documento (en nuestro caso de una petición http) depende de los datos que esta contenga. Debemos preguntarnos pues ¿qué define a una petición http? El primer elemento es la URL, dos peticiones serán distintas si su URL es distinta. Eso significa que peticiones que solo difieren en la URL (incluso si van a URLs sinónimas como pueden ser http://www.krasis.com y http://217.130.23.249) van a generar firmas digitales distintas. Otro elemento son los parámetros de la petición. HTTP permite que las peticiones lleven parámetros en varios sitios (query string, cuerpo, headers varios), así que OAuth define cuales son los posibles orígenes de los parámetros. En concreto se tomarán: 1. Los parámetros de la query string 2. Los parámetros en el cuerpo de la petición si esta viene como application/x-www- form-urlencoded 3. El valor del header Authorization, si este define que es de tipo OAuth, excluyendo el valor de realm si lo hubiese.
  • 13. Nos queda un tercer elemento. Podemos tener dos peticiones exactamente con la misma URL, con los mismos parámetros (en el mismo orden y situación si se quiere) pero que sean dos peticiones distintas si usan un verbo http distinto. Esos tres elementos se combinan en una cadena, que es la que se llama cadena base de firma (signature base string) y será esta cadena la que se firme digitalmente. Así pues la cadena base de firma incluye todo lo que es relevante de una petición http: su verbo, su URL y sus parámetros. El proceso de conseguir la cadena base de firma a partir de una petición de http se conoce como normalización de peticiones. Y es que, como veremos ahora, peticiones distintas, pero que signifiquen lo mismo, van a generar la misma cadena base de firma. ¿A que me refiero con peticiones no idénticas pero que signifiquen lo mismo? Pues que tengan los mismos parámetros pero en orden distinto, o que la URL sea igual pero difiera en mayúsculas o minúsculas. Creación de la cadena base de firma Para obtener esta cadena a partir de una petición http, debemos realizar unos pasos sencillos, pero de vital importancia (si nos equivocamos en esto, nuestra cadena base diferirá de la que calcule el proveedor de servicios y por lo tanto la firma digital será distinta, generando una petición inválida): 1. Obtener el verbo http usado, en mayúsculas (p.ej. POST o GET). 2. Obtener la URL normalizada. Esto significa que la URL se pasa toda a minúsculas. El valor del host y del port debe coincidir con el valor de la cabecera “Host”. La ruta hasta la query string se añade tal cual. El puerto se incluye solo si no es el estándar (80 para http o 443 para https). 3. Obtener una cadena con todos los parámetros de la petición. Para ello con independencia de donde estén (query string, cuerpo de la petición o cabecera Authorization) se ordenan por orden alfabético y se concatenan uno tras otro (nombre=valor). Si dos parámetros tienen el mismo nombre, se ordenan por su valor. Si un parámetro está vacío, aparece igualmente sin valor. 4. Se codifica la URL normalizada, siguiendo un procedimiento propio, llamado percent encoding. 5. Se codifica la cadena con todos los parámetros de la URL, siguiendo el mismo procedimiento anterior 6. Se crea una cadena con el valor de 1, el símbolo &, el valor de 4, el símbolo & y el valor de 5. Esta cadena obtenida en el punto 6 es la cadena base de firma, y de la cual se calculará el hash para obtener la firma digital de la petición. El método de codificación percent encoding Este método se usa solo para el cálculo de la cadena base de firma. Es un método muy parecido y basado en el método de codificación de URIs (definido por la RFC 3986 en su apartado 2.1). La RFC de OAuth 1.0, en su sección 3.6 define claramente como es esta codificación: 1. Se codifica la cadena en UTF8
  • 14. 2. Los siguientes caracteres: letras, números, “-“,”.”,”_” y “~” no son codificados y se ponen tal cual. 3. Cualquier otro carácter debe ser codificado usando %xx, donde xx es el código hexadecimal, en mayúsculas, del byte. Aunque el método parece idéntico al definido por el RFC 3986 en su apartado 2.1 no lo es. Hay una sutil diferencia: en OAuth se codifican todos los caracteres excepto los indicados en el punto 2. Mientras que en el RFC 3986 algunos caracteres no se codifican si actúan como separadores. Es un detalle importante. P.ej. la URL http://www.krasis.com codificada según la RFC 3986 es: http://www.krasis.com, mientras que usando el percent encoding de OAuth, los caracteres “:” y “/” se codifican igualmente, aun cuando forman parte del separador :// que separa protocolo de host. Así pues la URL queda como http%3ª%2F%2Fkrasis.com Así pues cuidado con usar métodos que codifiquen URLs, incluso aunque sean conformes al RFC 3986, ya que puede ser que no generen exactamente la misma cadena. Elementos de una petición OAuth Toda petición que llamemos petición OAuth deberá contener algunos elementos obligatorios que son los parámetros OAuth y la firma digital. No todos los parámetros son obligatorios en todo momento. El protocolo define un conjunto de elementos que toda petición OAuth debe tener, y que sirven para garantizar el buen funcionamiento de éste. Los que deben existir en toda petición OAuth son: 1. El identificador del cliente (Consumer Key). 2. Un timestamp: Usualmente el número de segundos desde el 01 de Enero de 1970. 3. Un número único (nonce) 4. El método de firma digital usado 5. La firma digital Luego, en algunas peticiones OAuth puede existir: 6. El identificador temporal (Request Token) 7. El identificador de acceso (OAuth Token) De todos estos elementos el punto 3 merece especial atención, por lo ambiguo de su definición. Realmente la especificación no dice mucho acerca de él, salvo que no tiene ni porque ser un número y que su uso está recomendado para poder discernir entre dos peticiones distintas dado un mismo timestamp. O sea que dos peticiones con el mismo timestamp y del mismo cliente, deben tener un valor de nonce. La especificación no dice si deben ser secuenciales o no, ¡de hecho ya hemos comentado que no tiene ni porque ser un número! Cada proveedor puede establecer sus reglas y los clientes deben adaptarse a ellas. De hecho su uso no es obligatorio, depende de cada proveedor de servicios. Parámetros OAuth El nombre de los distintos parámetros OAuth está definido por el protocolo y son los siguientes:
  • 15. 1. oauth_consumer_key: Identificador del cliente (Consumer Key) 2. oauth_timestamp: Timestamp de la petición 3. oauth_nonce: Valor del número único 4. oauth_signature_method: Contiene el tipo de método de firma digital que se usa. 5. oauth_signature: Contiene la firma digital de la petición 6. oauth_token: Contiene o bien el Request Token o bien el Access Token (en función del paso del flujo en el que nos encontremos). Adicionalmente a estos parámetros existen otros que se usan en momentos puntuales y que son los siguientes: 7. oauth_callback: URL que debe llamar el autenticador con el código de verificación en el flujo 3-legged OAuth. 8. oauth_token_secret: Credencial temporal privada / Access token privado (en función del paso del flujo en el que estemos) que nos devuelve el proveedor de servicios. 9. oauth_verifier: Código de verificación que devuelve el autenticador Al margen de esos se pueden definer parámetros adicionales y esos pueden empezar por oauth_ si así se desea (la especificación no lo prohíbe). Localización de los parámetros OAuth Estos elementos se pueden incluir en distintas partes de la petición: 1. En el querystring 2. En el cuerpo de la petición (si el content type es application/form-www-urlencoded) 3. En la cabecera Authorization, si esa indica que contiene datos OAuth. Esa es la manera recomendada por la especificación. La especificación señala que un proveedor OAuth debe soportar los parámetros OAuth en cualquier de esas partes de la petición y que debe vigilar que no haya elementos duplicados (p.ej. un parámetro oauth_nonce en query string y otro en la cabecera Authorization). Si se encuentran elementos duplicados debe devolverse un error, en lugar de usar uno de los dos en función de cualquier posible criterio de prioridad. Cabecera Authorization Como se ha mencionado, la manera preferida es en la cabecera Authorization, según muestra este ejemplo sacado de la propia RFC: Authorization: OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature_method="HMAC-SHA1", oauth_timestamp="137131200", oauth_nonce="wIjqoS", oauth_callback="http%3A%2F%2Fprinter.example.com%2Fready", oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D" La cabecera Authorization debe indicar que es de tipo OAuth y el parámetro realm de aparecer se ignora a efectos de OAuth.
  • 16. Como se puede ver el formato es nombre=”valor” (el valor está entrecomillado). Si un parámetro tiene un valor vacío debe aparecer nombre=”” (dos comillas dobles seguidas). Estríctamente hablando entre el nombre del parámetro y el signo de igual no se admiten espacios. Al igual que entre el signo de igual y la primera de las dos comillas dobles. Los parámetros van separados por una coma y un salto de línea opcional. Lo que es importante es que el valor del parámetro está codificado usando Percent Encoding (ver el valor del parámetro oauth_callback para un ejemplo). En la RFC (apartado 3.5.1) se especifica con todo lujo de detalles el formato de la cabecera Authorization. Flujos de OAuth Vamos a explorar los diversos flujos de OAuth que existen. La especificación en sí define un solo flujo, el conocido como 3-legged OAuth, pero vamos a explorar algunos flujos más que se pueden encontrar en distintos proveedores (como linkedin o twitter). Dos de ellos están pensados para aplicaciones de escritorio (o móviles) otro es para el caso de que queramos ejecutar servicios pero en nombre de ningún usuario en concreto y finalmente hablaremos sobre la pseudo-autenticación usando OAuth (el famoso “sign with Facebook” que se ve en numerosas web). Esos flujos se diferencian tan solo por la forma en que el cliente (ya sea otra web o una aplicación de escritorio) consigue los tokens OAuth definitivos). Empecemos por el flujo definido por la propia especificación 3-legged OAuth Este es el flujo más conocido de OAuth y por el cual realmente fue creado. En este caso se asume que el cliente es capaz de tener un endpoint accesible para que el autenticador le pueda enviar el código de verificación. Evidentemente esto solo es posible si el cliente es una aplicación web. Pero vayamos paso a paso... El primer paso es que el cliente realice una petición OAuth para pedir un par de tokens temporales. Esos tokens temporales (conocidos comúnmente como request token and secret) son los que usarán en todo el flujo hasta terminar obteniendo los tokens definitivos (conocidos como access token and secret). Para obtener estos tokens el cliente básicamente se identifica a si mismo (usando su consumer key) y envía un parámetro llamado oauth_callback que es a donde debe recibir el código de validación que le servirá para obtener los tokens definitivos. El proveedor de servicios responde a dicha petición con los tokens temporales contenidos en los parámetros oauth_token y oauth_token_secret. ¡Todo el proceso ya se ha puesto en marcha! Ahora el cliente debe llamar al autenticador pasándole el Request Token que ha recibido. Esta petición, como va contra el autenticador y no contra el proveedor de servicios no es una petición OAuth. Es decir, el cliente no se identifica a sí mismo, ni la petición va firmada. El autenticador comprueba que el token temporal es válido, mira cual fue el cliente que lo solicitó (el proveedor de servicios debe haber guardado esta información en algún sitio accesible para el autenticador) y entonces pueden suceder varias cosas:
  • 17. 1. Que el token temporal pasado no sea válido: Se muestra un mensaje de error al usuario. 2. Que el token temporal sea válido y que el usuario NO esté autenticado contra el autenticador. El usuario recibirá el formulario de login del autenticador donde se le pedirán sus credenciales y que acepte dar permisos a la aplicación indicada. Si el usuario se autentica y da los permisos se sigue al punto 4. 3. Que el token temporal sea válido y el usuario esté autenticado. Si el usuario NO había dado permisos a la aplicación indicada se le pedirá que le de esos permisos. Si el usuario ya los había dado se seguirá al punto 4. 4. El autenticador redirige al usuario a la dirección de callback que especificó el cliente en la primera petición. La dirección de callback recibirá dos parámetros: el token temporal y un código de verificación. ¡Ya casi estamos! Una vez el cliente recibe en su dirección de callback una petición, junto con un token temporal y un código de verificación debe: 1. Asegurarse que el token temporal es el mismo que él ha generado 2. Realizar una petición OAuth al proveedor de servicios mandándole el token temporal (Request Token) y el código de verificación. La respuesta a esta petición OAuth serán los tokens finales (Access token and secret) que se usan para identificar llamadas OAuth en nombre del cliente autenticado. Cliente escritorio – Autenticación por PIN Cuando el cliente es una aplicación de escritorio el proceso es un poco más pesado para el usuario, ya que el cliente no puede especificar una dirección de callback. En este caso se usa lo que se llama out-of-band configuration. El tema está en que la especificación lo menciona explícitamente, pero luego no dice nada más acerca de este modo de configuración. Así que este apartado está basado en cómo se ha implementado en Twitter. Este método es válido para aplicaciones que pueden abrir una ventana de navegador (aunque no puedan interaccionar con ella). La primera petición es idéntica al flujo tradicional, salvo que el valor de oauth_callback debe ser oob. Este valor está reconocido por la especificación para indicar que el cliente quiere usar el método de configuración out-of-band. La respuesta del proveedor será, igual que antes, el par de tokens temporales (Request Token y Request Secret). La segunda petición del cliente será contra el autenticador. Puede ser que se use el mismo endpoint que el caso anterior, o puede que no. Dependerá de cada implementación, aunque lo normal es que se usen endpoints distintos del autenticador para poder personalizar el comportamiento de éste en cada caso. El comportamiento del autenticador debe ser el mismo que en el flujo anterior, aunque son posibles algunas variantes. P.ej. Twitter obliga a aceptar de nuevo los permisos incluso aunque se hubiesen aceptado previamente para el mismo cliente. La principal diferencia con el flujo 3-legged es que una vez el usuario se autentica y da los permisos a la aplicación, al no haber dirección de callback a la que redirigir el usuario, el autenticador mostrará una página especial con un código (PIN) que el usuario deberá entrar a la aplicación.
  • 18. El usuario entra el código PIN a la aplicación, y la aplicación usa este código PIN como si fuese el código de verificación: es decir, realiza una llamada OAuth al proveedor de servicios con el Request Token, el PIN entrado por el usuario y obtiene los tokens OAuth definitivos. Cliente escritorio – autenticación por password Otro flujo posible para aplicaciones cliente que no pueden mostrar ni una ventana de navegador, es mandarle al autenticador el login y password del usuario. Claro que eso implica violar uno de los principios de OAuth: que el cliente nunca tiene acceso al login y password del usuario. En este caso el usuario debe introducir su login y su password, pero solo una vez, después la aplicación cliente no los usa nunca más, ya que el resto de peticiones son OAuth. Por supuesto estamos ante un tema de confianza de la aplicación. Si yo me descargo la aplicación oficial de Facebook, pongamos por caso, no tendré problemas en introducir mi login y password en ella. Si me descargo una aplicación realizada por Hackers. Inc. Pues seguramente no la entraré si me la pida (aunque la aplicación pueda ser legítima, yo no tengo manera de saberlo). Como siempre el primer paso del flujo es idéntico: una petición OAuth del cliente para obtener los tokens temporales, mandando “oob” como valor de Oauth_callback. Una vez tiene los tokens temporales, el cliente debe puede llamar al autenticador, pasándole el Request Token junto con el login y el password del usuario. El autenticador comprueba las credenciales y en caso de que sean correctas, responde con el código de verificación (debe notarse que el autenticador asume que el usuario da permisos a la aplicación, cosa lógica teniendo en cuenta que ha entrado su login y password en ella). La aplicación una vez tiene el código de verificación, reanuda el flujo normal: manda el código de verificación junto el token temporal al proveedor de servicios para obtener los tokens definitivos. A partir de este punto todas las llamadas pueden ser OAuth y el login y password del usuario se pueden descartar. 2-legged OAuth Hay mucha confusión sobre que es 2-legged OAuth y existe básicamente porque es una forma de usar OAuth que no se menciona nunca en la especificación, donde una aplicación autoriza a otra aplicación a utilizar recursos protegidos, pero en este caso no se está involucrando a ningún usuario. Todo el flujo de adquisición de tokens desaparece: si el cliente está registrado en el proveedor (es decir tiene su par de claves) en lugar de usar el flujo normal y solicitar un par de tokens temporales, lo que hace es: 1. Realizar una llamada OAuth, usando su clave pública como Access Token (y firmando con el Client Secret). El proveedor de servicios puede verificar que la clave pública pertenece a un cliente registrado y conocido, puede verificar la firma y si esa es correcta ejecuta la petición. En este caso la petición no se realiza en nombre de ningún usuario. Pseudo-autenticación con OAuth El flujo final que nos queda por ver es el de pseudo-autenticación, es decir cuando una web permite autenticar a sus usuarios con las credenciales de un proveedor OAuth. Lo llamamos pseudo-autenticación, porque a diferencia de un sistema de autenticación puro, como puede
  • 19. ser OpenID, en el cual se pide la identidad del usuario, en el caso de OAuth se intenta acceder a un recurso protegido en nombre de un usuario y el propio flujo de OAuth hará que el usuario se autentique contra el proveedor de servicios. El cliente en este caso no sabe cuál es la identidad del usuario, pero tiene un token OAuth a través del cual puede acceder a una API y preguntar por su nombre. Ilustración 2: Autenticación OpenID y pseudo-autenticación OAuth (fuente: Wikipedia) Míralo de este modo: Si yo quiero saber quién eres tú, tengo dos modos de hacerlo: 1. Pedirte que me muestres un documento que te autentique. Por supuesto ambos debemos acordar que tipos de documentos son válidos para autenticarte (el DNI es válido pero la tarjeta de la biblioteca, no). 2. Pedirte las llaves de tu casa, entrar en ella contigo, abrir tu cartera y mirar tu DNI. La primera sería una autenticación pura basada en un protocolo como OpenID. La segunda sería pseudo-autenticación basada en OAuth. En el ejemplo del segundo punto, he puesto contigo adrede, para que quede claro de que no puedo hacer lo que quiera cuando esté en tu casa: tan solo puedo hacer lo que tú me hayas autorizado a hacer. Realmente este flujo es idéntico a cualquiera de los tres flujos anteriores que hemos visto. Todos los pasos son idénticos y la experiencia del usuario es la misma. La única diferencia está en el cliente: antes el cliente solo quiere realizar una llamada a un servicio, mientras que ahora si la llamada OAuth es exitosa, el cliente autentica al usuario dentro de su propio sistema. De esta manera el usuario obtiene acceso a una determinada aplicación web usando sus
  • 20. credenciales de otro proveedor OAuth (como pueda ser Facebook o Twitter). Para desarrolladores de aplicaciones es muy interesante, porque no solo evitan que el usuario deba darse de alta en su sistema, si no que además tienen acceso a los datos que el proveedor de OAuth exponga de ellos (p.ej. podrían acceder al perfil de Facebook).