Modelo de apps en detalle (II): Las piezas

August 21, 2014

En el primer post de esta serie sobre el modelo de apps de SharePoint 2013, expliqué la problemática de tener código a medida en SharePoint y como SharePoint ha evolucionado para acomodarla, hasta llegar al modelo de apps en SharePoint 2013.

En este segundo post voy a explicar las piezas clave del modelo de apps, para asentar los conocimientos básicos antes de meternos en detalle con la autorización y la autenticación de la app.

Los "webs" del modelo de apps

A grandes rasgos, el modelo de apps involucra tres piezas básicas en forma de sitio web:

  • "host web" (SharePoint)
  • "app web" (SharePoint)
  • "remote web"

Voy a poner un diagrama completo de las piezas de las apps y lo comentaremos a lo largo de este post. Entender bien estas piezas y su relación es tener la mitad del trabajo hecho. Vayamos por partes.

image  

Host Web

Las apps se instalan en un sitio de SharePoint y se lanzan desde allí. Ese sitio web, en el que la app está instalada y tiene ciertos permisos, se llama host web.

App Web

Una app al instalarse puede crear un sitio de SharePoint para su propio uso. Este sitio, si existe, se llama app web y tiene la URL con un dominio diferente al de host web. Esto se hace para impedir llamadas cross-site de JavaScript.

¿Para qué nos sirve un app web? La idea es guardar aquí los datos propios de la app, como los resultados parciales, configuraciones, perfiles de usuarios etc. La app web es invisible para el usuario normal de SharePoint, y no se puede acceder a ella mediante la interfaz de usuario.

Remote Web

Para las aplicaciones provider-hosted (es decir, las que tienen código y no sólo JavaScript), la invocación de la app tiene forma de redirect hacia una URL en la que está alojada la aplicación. Este sitio donde está alojada la app se llama remote web. Lo más probable es que la app esté alojada en un IIS (on-premise o en Azure) pero podría estar alojada en cualquier tecnología web (Apache, Linux, Node.js…). Sin embargo, si usamos ASP.NET como la plataforma para la app, se nos simplifica la comunicación con SharePoint ya que disponemos de librerías y helpers.

Los permisos

Pongamos como ejemplo que acabamos de clicar el enlace de la app en SharePoint, concretamente en http://contoso/site1. . Como ya sabéis, esto implica que la app está instalada en http://contoso/site1, que es la host web de la app.

La app también tiene ciertos permisos sobre la host web, que se le otorgan al instalarla. Los permisos pueden ser de leer algunas listas de la host web hasta tener control total sobre la tenancy o la site collection en la que está la host web. Los permisos de declaran en el paquete de la app (que veremos más adelante) y la persona que instala la app tiene que tener la potestad de otorgarlos.

Resumiendo, la app tiene los permisos sobre la host web que le hayamos dado al instalarla. Ni uno más ni uno menos.

Si la app dispone de una app web (que es otro de los parámetros que podemos poner en el paquete de la app), la app tiene el control total sobre la app web. Puede hacer y deshacer lo que le dé la gana. Como la app web no se muestra al usuario y sirve como un mero repositorio de datos para la app, no hay peligro en darle control total sobre esa parte de SharePoint.

Para nuestro ejemplo, imaginemos que la app web tiene la url http://app123.contosoapps.

La comunicación entre SharePoint y la app

Volvamos al ejemplo. Hemos clicado la app en http://contoso/site1 y nos ha llevado a https://wingtip/app1/start.aspx. Esta URL es parte del paquete de la app, y es la que lleva a la remote web de la app. En este caso, imaginemos que https://wingtip/app1 es un sitio IIS en una máquina dentro del datacenter de Contoso. Una máquina que no tiene ni idea de SharePoint y que contiene una app hecha en ASP.NET WebForms.

ASP.NET carga la página start.aspx. En este momento la app tiene que establecer la conexión con SharePoint para cargar los datos que necesita de allí. Veamos como lo hace.

Lo primero que necesita la app en remote web es saber a qué URLs tiene que llamar para obtener los datos de la host web y la app web.

¿Cómo lo sabe? Podríamos guardar estas URLs en la configuración de la app (en web.config o en la base de datos) pero lo más habitual es que al llamar la app desde SharePoint se incluyan estas URLs en la URL con la que se llama a la app. Así, nuestra app no se llama con un redirect a https://wingtip/app1/start.aspx sino a https://wingtip/app1/start.aspx?SPHostUrl=http://contoso/site1&SPAppWebUrl=http://app123.contosoapps. Como podéis ver, en los parámetros SPHostUrl y SPAppWebUrl tenemos las URLs de la host web y de la app web, respectivamente.

image

Usando el modelo de objetos de cliente de SharePoint podríamos instanciar un contexto a través de esas URLs, pero nos faltaría la autenticación. Es decir, ¿con qué credenciales de usuario abrimos el contexto de SharePoint? Vamos a ver como lo resuelve el modelo de apps.

Autenticación de la app

En el primer post de esta seria dije que las apps de SharePoint 2013 tienen identidad propia y se les pueden asignar permisos. Pues este es el mecanismo con el que se resuelve el problema de las credenciales: el contexto de SharePoint se abrirá con las credenciales de la app.

¿De dónde vamos a sacar las credenciales de la app? Esto depende de si estamos usando las apps en SharePoint Online o una granja on-premise federada con Azure Access Control Service (ACS) o bien estamos usando las apps en un entorno on-premise con certificados.

El primer caso es el más frecuente y se llama "low-trust" (baja confianza). En este caso, SharePoint usa un servicio de Azure llamado ACS (Access Control Service) para confimar la identidad de la app. ¿Cómo? Pues sencillamente antes de hacer el redirect a la app, inyecta en la cabecera de la petición HTTP un pequeño fragmento de texto, un token de contexto, que le servirá a la app luego para sacar las credenciales.

image

Este token de contexto contiene la información sobre la identidad de la app. La app (ASP.NET) tiene que extraer este token de la petición inicial HTTP, hacer una petición a ACS e intercambiarlo por otro token, llamado token de acceso. El token de acceso nos sirve para instanciar un contexto de SharePoint, ya que es un token OAuth que SharePoint 2013 acepta. Este token se incorpora en la cabecera de la petición a la interfaz REST de SharePoint 2013 con el nombre de "Bearer".

image

Podéis ver el contenido exacto de los tokens de contexto y acceso en el siguiente enlace: http://msdn.microsoft.com/library/office/fp179932.aspx#Tokens.

Todo este proceso de extraer los tokens, validarlos, intercambiarlos y crear el contexto de SharePoint está encapsulado en una clase autogenerada por Visual Studio al hacer una app de SharePoint, que se llama TokenHelper.cs. Podéis examinarlo y ver como hace la petición a ACS y que luego incorpora el token de acceso para llamar a SharePoint.

Si estamos en una plataforma que no es .NET (como PHP por ejemplo), podemos hacer el mismo proceso pero no tendremos un TokenHelper mágico. Tendremos que hacer la extracción y construcción de tokens y de llamadas a ACS de manera manual, pero no hay nada intrínsecamente difícil en ello.

Resumiendo

Como podéis ver, el "baile" entre las piezas de las apps es delicado y hay muchos conceptos involucrados. Os recomiendo releer este post hasta que os quede claro la interacción entre host web, app web y remote web, así como el papel de los tokens. Si queréis más detalles sobre los tokens y la autenticación low-trust, os recomiendo el artículo siguiente de Kirk Evans del equipo de SharePoint (en inglés): http://blogs.msdn.com/b/kaevans/archive/2013/04/05/inside-sharepoint-2013-oauth-context-tokens.aspx.

En el siguiente post veremos como las aplicaciones "high-trust" resuelven el problema de la autenticación sin delegarlo a un servicio de terceros como ACS.


Profile picture

Written by Edin Kapić Insatiably curious code-writing tinkerer. Geek father. Aviation enthusiast. Cuisine journeyman. Follow me on Twitter