Varias semanas atrás leí un artículo acerca de cómo desarrollar aplicaciones web más seguras cuando se hace uso de AJAX y el artículo me dio pie a escribir esta entrada, ya que estoy convencido de que para muchos de nosotros desarrollar aplicaciones más seguras es uno de los objetivos principales.

Cuando desarrollamos aplicaciones web, podríamos afirmar que en la mayoría de casos la arquitectura que se acaba implementado es una arquitectura en dos capas (Cliente – Servidor) cómo la que se muestra en la imagen:

 

Arquitectura en dos capas

Arquitectura en dos capas

Ésta arquitectura lleva implícito un riesgo si utilizamos AJAX en el cliente: el front-end accederá al back-end haciendo uso de los servicios que éste último publica mediante una interfaz o API. El riesgo consiste en que estos servicios son públicos (sino no podríamos acceder a ellos mediante AJAX o Silverlight), es decir, que están abiertos a cualquiera que quiera hacer uso de ellos (sea mediante nuestro cliente o a través de cualquier otro canal). El caso más habitual es el uso de WebServices en la parte back-end. Estos servicios web són incapaces, por si mismos, de diferenciar si la llamada está siendo efectuada por un cliente propio o por un agente externo (y probablemente con intenciones maliciosas) ya que lo único que el cliente hace es llamar una URL con un conjunto de parámetros y recibir la respuesta del servicio. 

Cualquier barrera que planteáramos poner en este nivel (firewalls, por ejemplo) privaría de acceder al servicio tanto a propios como ajenos, por lo que nadie podría acceder al mismo.

Si no se hiciera uso de AJAX, esto no sería un problema, puesto que la llamada al servicio se realizaría desde el propio Servidor, y esta ya se encuentra controlada ya que el servidor ya se encarga de comprobar que el usuario que realiza la petición se encuentre autenticado y esté autorizado (ASP.NET Authentication).

En caso de utilizar AJAX, sería necesario implementar esta comprobación por nosotros mismos.

Actualmente se ha aceptado como diseño de arquitectura, colocar una capa llamada Capa de servicios (o Service layer) que es la capa a la que accede el front-end (AJAX en este caso) y que se encarga de gestionar todos los pasos necesarios para generar la respuesta esperada por el cliente (la capa de servicios se encarga de acceder a los servicios, objetos de negocio o de ejecutar workflows (flujos de trabajo) con tal de obtener una respuesta correcta). Aun así, esta capa no nos proporciona la seguridad esperada si accedemos a ella mediante AJAX o Silverlight (es decir, de forma asíncrona) ya que sigue siendo imposible determinar si la llamada proviene de un cliente autorizado o de un cliente que no lo está.

La solución que se propone es añadir una capa intermedia, entre el front-end y la capa de Servicios, con tal de que esta quede protegida. Esta capa se denomina AJAX Service Layer (o capa de servicios AJAX) y es la capa a la que se conecta el front-end y la encargada de comprobar que éstos dispongan de los permisos adecuados para poder acceder a dicho servicio. Para hacernos una idea, la arquitectura propuesta es la siguiente:

 

Capa de servicios

Capa de servicios

 

 

Arquitectura con AJAX Service Layer

Arquitectura con AJAX Service Layer

 

 

 

Pero vayamos paso a paso:

Con tal de implementar seguridad en aplicaciones que utilicen Silverlight o AJAX, se propone utilizar, tal y como se ha comentado, una capa intermedia, llamada Capa de Servicios AJAX (AJAX Service Layer). Las aplicaciones cliente (entiéndase AJAX o Silverlight) deberán realizar cualquier petición a la capa de servicios AJAX (ya que la situaremos entre el front-end y la capa de servicios (Service Layer). 

La responsabilidad de la capa de servicios AJAX es comprobar si la llamada que esta recibiendo proviene de un cliente autorizado o no. Si la comprobación resulta afirmativa, lo que se hará es llamar al correspondiente servicio de la capa de servicios (Service Layer) con tal de devolver la respuesta esperada. En caso negativo, se lanzará un error.

¿Y cómo determinará la capa de servicios AJAX si la llamada proviene de un cliente autorizado? Pues muy simple: comprobaremos que el usuario esté autenticado. ¿Cómo? una llamada AJAX hace un Postback del estado actual de la aplicación. Entre los datos que recibimos estará la Cookie de Autenticación. Podremos, así pues, comprobar que el usuario esté autenticado. 

Obviamente, para ello deberemos hacer pasar al usuario por un proceso de autenticación y autorización previamente a la utilización de aquellos servicios que requieran la autenticación del usuario por motivos de seguridad. No está de más recordar como se configura la autenticación y autorización de usuarios. En el archivo web.config podremos especificar la autorización de un grupo de usuarios creando una entrada como la siguiente:

 

<location path="MembersOnly">
    <system.web>
        <authorization>
            <deny users="?" />
        </authorization>
    </system.web>
</location>

Para especificar el modo de autenticación (Forms, Windows Integrated, Passport,etc..) se puede crear una entrada tal que esta:

<authentication mode="Forms">
    <forms loginUrl="MembersOnly/login.aspx">
    </forms>
</authentication>

Y eso es todo. Si tenéis cualquier duda o propuesta de mejora para esta solución, no dudéis en dejarla patente en forma de comentario. La discusión y el debate nos harán a todos mejores programadores.😉

Hasta pronto!:)