Spring social

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:

  • Service Provider: Es el site, web-service o servicio en general donde se localizan los recursos restringidos (y que por tanto hay que proteger mediante un sistema de autenticación/autorización). El protocolo no obliga a que el Service Provider sea adicionalmente el servicio de identidad, con lo que puede usar su propio mecanismo para realizar la autenticación de los usuarios.
  • Usuario. El usuario es el actor principal dentro de OAUTH y es la persona que dispone de recursos privados que no quiere hacer público en el Service Provider, pero que quiere compartir con otro site/sistema.
  • Consumer: Se trata de la aplicación que está accediendo al recurso privado del usuario. Es por tanto, dicha aplicación la que mediante los permisos otorgados por el usuario el que accederá finalmente al recurso.
  • Recursos protegidos: Aquellos recursos que son privados, y para los que se le otorgan permisos al Consumer explícitamente para que proceda a procesarlos adecuadamente: fotos, documentos, contactos, …
  • Tokens: Dentro del protocolo se usan tokens como sustituto a las credenciales del usuario. Se usan técnicas de Firma Digital (par de claves pública-privada, algoritmos de hashing, etc..) para cifrar la información asociada al token y para garantizar la identidad de la persona/sistema que realiza la petición (Usuario/Consumer). Dentro del protocolo hay dos tipos de tokens: Request y Access. Uno asociado con el Consumer y otro asociado con el Usuario. A continuación entramos en detalle.

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: uno en el que se autentica el Consumer (aplicación que quiere obtener recursos protegidos, pero que delega la autenticación en el service Provider). Posteriormente hay una segunda etapa de autenticación donde el usuario debe autenticarse en el sistema para poder ser identificado correctamente. A partir de esta segunda fase y mediante el mecanismo de tokens que estamos definiendo, es posible que el Consumer pueda acceder al recurso protegido (puesto que el usuario le ha dado los permisos oportunos).

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 http://lanyrd.com/ 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.

Federico Caro es un consultor senior con más de 10 años en el desarrollo de aplicaciones/sistemas basados en tecnología J2EE. Su carrera profesional en J2EE comenzó en Peoplecall una empresa dedicada a servicios de telefonía IP, colaborando en el desarrollo de la migración del site de PHP a J2EE integrando los servicios de facturación. Posteriormente ha pasado por departamentos de definición de arquitecturas J2EE en Indra Sistemas, Ralia Technologies (Grupo Damm) e IT-Deusto.

Ver toda la actividad de Federico Caro

Recibe más artículos como este

Recibirás un email por cada nuevo artículo.. Acepto los términos legales

Escribe un comentario