El «sexto» mandamiento de SOA, es decir, el sexto principio, dice que los servicios no deben tener sesión.
Aunque todavía hay algunos que se empeñan en tener servicios con estado, por extraño que nos parezca, creo que la mayoría tenemos claro que implementarlos sin él hace que los servicios se puedan ejecutar de manera más autónoma, sin depender de infraestructura dedicada a mantener la sesión y que también aumenta su rendimiento y escalabilidad.
Sin embargo, hay ocasiones en que es un poco difícil mantener este principio en la práctica. ¿Por qué digo esto? Por ejemplo tenemos el caso de las webs «modernas».
Afortunadamente, las aplicaciones web actuales han superado el modelo antiguo basado en páginas web «tontas» que se basaban en el esquema de pinto la página, envío la petición al servidor y refresco la página con la que me devuelve.
Las aplicaciones web actuales se parecen más desde luego a lo que conocíamos como cliente/servidor en el escritorio. Son capaces de mantener el estado de la aplicación haciendo prácticamente innecesario mantener la sesión en el servidor. Es decir, toda la interacción con el usuario, la presentación y el control. Y es que como una vez escuché en una conferencia… corren buenos tiempos para el desarrollador de backend, sólo tiene que preocuparse por una invocación al servicio y dar una respuesta. El resto se lo tienen que «comer» los desarrolladores de frontend.
Hasta aquí bien, pero hay algunos aspectos que tenemos que cubrir, por ejemplo, dos cosas con las que nos encontramos:
- las credenciales de usuario para la autenticación
- información básica del usuario
En estos dos casos, sí que parece tener sentido guardar esto información en sesión. Hay que tener en cuenta que los frontales se han hecho así durante muchos años, y de hecho, es una forma bastante común.
Con las credenciales tenemos por supuesto la opción de enviar una cabecera HTTP «Authorization» con el usuario+contraseña en base64, lo que conocemos como seguridad BASIC. Así pues, en cada invocación, desde el frontal hay que mandar esta información sensible (por lo que preferiblemente hay que hacerlo mediante HTTPS).
Dejando aparte el tema de la confidencialidad, que garantiza el uso del protocolo seguro, en cada recepción hay que validar las credenciales (accediendo al repositorio de passwords o hash de passwords). No podremos además poner una caducidad a esas credenciales para que sean válidas durante unos minutos u horas. De tal manera que si el usuario se le olvida cerrar el navegador alguien podría seguir ejecutando la aplicación sin permiso.
La solución a todo esto es un usar un token, que se envía como cabecera en cada invocación del frontal. Pero no cualquiera, uno del tipo de JWT. Una posible implementación sería esta y el aspecto que tiene es un «churro» de texto como este:
eyJhbGciOiJIUzI1NiJ9.SGVsbG8sIHdvcmxkIQ.onO9Ihudz3WkiauDO2Uhyuz0Y18UASXlSc1eS0NkWyA
Además de ser seguro, tener un timesamp con el que podemos controlar su caducidad, también podemos almacenar en él cierta información del usuario (como el email o el id de usuario) de tal manera que nos evitamos tener que hacer consultas constantes… y de paso solucionamos el otro tipo de información que se solía guardar en sesión: la información básica de usuario.
En definitiva, el uso de un token de seguridad que se reenvia en todas las invocaciones al servidor es una práctica común y que tiene soluciones ya conocidas y usables, sin tener que reinventar la rueda… y por sobre todo, por favor, haced los servicios sin sesión.
13/09/2015 at 19:50
No tengo ninguna objección a lo que tu presentas, que es tecnicamente correcto, pero omitis aclarar a tus lectores que estás partiendo de una implementación JSON y no SOAP/XML. El uso de JWT es una opción ligada al uso de JSON, pero si tus lectores trabajan con SOAP/XML, entonces tendrán que recurrir a otros token, como por ejemplo, el token Username, o SAML o X.509 como certificado. Asumo que un token JWT no podrá viajar en encabezados SOAP.
Tu referencia a sesiones es correcta, pero de nuevo, omitis que si los lectores trabajan con SOAP/XML entonces tendrán que referirse a los mecansimos de Gestor de Autentificación, token de contexto de seguridad y en general, WS-Trust, como ejemplo.
Por lo demás, tu artículo es interesante en cuanto pretende abordar la seguridad, pero la seguridad en SOA no puede limitarse al mero trecho entre el usuario humano y las aplicaciones. Supongo que será material para sesiones adicionales que seguramente serán tan o más interesantes. Cordialmente. Yves Chaix (ychaix@arcitura.com)