Estas últimas semanas he estado preparando la charla en Spring IO del 2011. Llevo siguiendo la pista a proyectos tan interesantes como Spring Data, Spring Mobile, Spring Roo, Spring integration, etc.

Pero, finalmente todas estas temáticas estaban planificadas por algún otro ponente, con lo que revisé los proyectos más novedosos de Spring, encontrándome con Spring Social.

Aunque el proyecto está en un estado muy embrionario y no existe mucha documentación al respecto, lo cierto es que ofrece una funcionalidad básica, pero que a la vez abre el abánico de numerosas posibilidades para poder integrarnos con las principales redes sociales: Twitter, LinkedIn, Facebook, Tripit...

Quizás la mayor carencia que sufra estas primeras versiones de Spring Social es que no han incoporado la integración con OAuth y se debe hacer con una librería externa (la más recomendable Scribe). Pero claro, para los iniciados, debería empezar por definir qué es esto de OAuth.

OAuth es un estándar que permite un sistema de autenticación delegada. El protocolo presenta los siguientes conceptos básicos:

Para aclarar los conceptos pongamos un ejemplo. Supongamos que estamos desarrollando un servicio de impresión de fotos y queremos que el usuario pueda imprimir las fotos alojadas en un sistema como Flickr.

Con este escenario, el ServiceProvider sería Flickr, puesto que es el sistema donde están los recursos protegidos (en nuestro caso, fotos). El rol de Consumer sería la aplicación de impresión de fotos, el usuario sería la persona que quiere imprimir unas fotos de su cuenta de Flickr, pero no quiere que la aplicación de impresión conozca sus credenciales, incluso no quiere tener unas credenciales específicas en este site. Los recursos protegidos serían las fotos alojadas dentro de Flickr.

Veamos el detalle del flujo del protocolo.

OAUTH: Flujo de autenticación

Normalmente hay un paso previo, que no aparece en el diagrama y que consiste en la necesidad de registrar la aplicación (Consumer) en el Service Provider, proceso que te devuelve un par de valores ConsumerKey y Consumer Secret. Básicamente estos dos datos se comportan como una clave pública y una clave privada en un proceso de firma digital. De hecho como se puede ver en el detalle de parámetros de las distintas peticiones, en algunas de ellas se pasa la clave pública (Consumer Key). Puesto que la clave privada es compartida entre el Consumer y el Service Provider, éste forma parte de la signature incluida en el Token de Petición. Como en cualquier proceso de firma electrónica, esta clave privada será usada en el destino para comprobar la veracidad/integridad de la petición.

A continuación, comentamos los datos más importantes del flujo expuesto:

En la primera petición (A), como se puede ver el Consumer al custodiar las claves Consumer Key y Consumer Secret, usa estas llaves para enviar una petición al Service Provider para que éste identifique el sistema que quiere realizar la petición. Destacar que en el protocolo Auth, es un proceso de autorización en el que interviene básicamente Service Provider, Consumer y Usuario, produciéndose la autenticación en dos pasos básicos:

Centrándonos ahora en la petición (A), se ve que dentro de la petición se incluye la clave pública del consumer (identifica al consumer), además se genera un campo signature que básicamente consiste en construir una cadena de caracteres base (normalización de la petición http incluyendo el método http, parámetros, URL callback, adicionalmente se usa la clave privada para generar finalmente la signature), la cual va incluida dentro de la petición.

Como hemos comentado adicionalmente dentro de la petición se indica la URL de callback, es decir la URL del Consumer a donde se debe redirigir el flujo una vez el usuario se ha autenticado en el Service Provider.

Una vez construida la petición con sus parámetros, el Service Provider realiza el correspondiente proceso de autenticación (procesamiento del parámetro signature) con la clave privada compartida, y garantizando por tanto, que la petición no ha sido alterada y comprobando mediante este algoritmo matemático que el peticionario de la petición es quien dice ser. Tras comprobar la integridad/veracidad de la petición, el Service Provider contesta al Consumer con la clave pública y privada que el usuario deberá usar en el proceso de autenticación de la segunda etapa del protocolo).

Una vez realizado este proceso, el Consumer redirige al Service Provider para que tenga lugar el proceso de autenticación del usuario. Es en este paso, donde el usuario se autentica usando las credenciales del Service Provider.

Si para autenticación se produce de un modo correcto, el Service Provider manda el token y un verificador que el Consumer usa para construir el segundo de los tokens (AccessToken). Este token será el que lleva incorporado la autorización implícita del usuario y por tanto, el que concederá al Service Provider la posibilidad de acceder a los recursos privados del Service Provider.

Normalmente en el proceso de autenticación del usuario, se pueden otorgar diferentes permisos (acceso a datos personales del usuario, acceso a las fotos, posibilidad de enviar correo electrónicos al usuario, etc...). Es en el token donde reside el proceso de autenticación delegada, donde el usuario delega al Consumer la posibilidad de poder acceder a sus recursos. El protocolo permite que este token sea invalidado en cualquier momento, disponga de un tiempo de vigencia, etc.

Una vez el Consumer dispone del token de acceso, se produce un intercambio similar al realizado para el Request Token, finalizando con el acceso por parte del Consumer a los recursos privados del usuario.

Como he comentado al inicio del post, Spring Social no incluye una integración completa con el protocolo OAuth, quizás su mayor defecto en estas primeras versiones, con lo que es necesario utilizar una librería como Scribe para poder completar la integración con las principales redes sociales.

Spring Social básicamente incluye una serie de Templates (LinkedInTemplate, FacebookTemplate, TwitterTemplate, …) que nos ofrecen acceso a datos de las respectivas redes sociales. Además incluye clases para firmar las distintas peticiones siguiendo la especificación definida por el protocolo OAuth.

Finalmente, tiene una librería de tags para realizar la integración con Facebook y una integración con Spring MVC (ArgumentResolver) que permite realizar el binding entre parámetros de la petición HTTP y argumentos de un controlador de SpringMVC, para aislar al programador de las particularidades de la integración con Facebook (obtención del Token de Acceso y el identificador de usuario de Facebook).

Conclusiones

Aunque, inicialmente el proyecto es muy pequeño (unas decenas de clases), y en un primer análisis puede parecer poca la funcionalidad que ofrece, sinceramente se nos abren amplias posibilidades funcionales que permiten enriquecer nuestras aplicaciones obteniendo información de las principales redes sociales. De hecho, esta última semana he conocido y al principio, aparte de que me encantó la idea y la tienen implementada con muchísima calidad, no dejaba de ser una aplicación donde se ofrecía información de los principales eventos del mundo organizado por año, por topic, etc.

Pero curiosamente descubrí la integración que tenía con Twitter (siguiendo el protocolo OAUth anteriormente mencionado) y cuando finalizo el proceso de autenticación, me apareció el evento en el que participaba, los eventos que mis seguidores estaban interesados…

En definitiva, se personalizó el site en base a la información que proporciona Twitter. Es un ejemplo de que, a veces, las cosas sencillas permiten un abanico funcional muy interesante, y más si tenemos en cuenta la orientación social del actual panorama web. Y finalmente, si Spring me ofrece una API que permite integrarme de una manera homogénea a las principales redes sociales, mejor que mejor.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.