Muchos departamentos de IT ven SharePoint como un elemento aislado y que no lo pueden integrar con muchos de sus sistemas. Principalmente por este motivo muchos responsables de departamento no quieren un SharePoint dentro de sus infraestructuras. Ahora bien, esta idea se puede contrastar con algo de conocimiento sobre nuestro «servidor preferido».
En este post vamos a ver un ejemplo práctico de cómo podemos utilizar una WebAPI 2 con nuestro SharePoint.
Introducción
Mi compañero Alberto ya escribió recientemente como implementar una Provider Hosted que no erá tal. En esta ocasión, introducimos un sistema de validación dentro de SharePoint, para generar Tokens de autorización sobre SharePoint, pero partiendo de la base de que el otro sistema previamente se había autenticado contra SharePoint.
¿Cual es el problema que tiene está forma?
El principal problema es que estamos asumiendo que nuestro cliente origen será un Navegador que se ejecuta en un ordenador que corre bajo un sistema operativo Windows. Ahora bien, actualmente estamos en un proceso de cambio en el que todo el mundo quiere abrir sus aplicaciones desde cualquier periférico y con muchas variedades de sistemas operativos y también desde diversas aplicaciones, por lo que, «obligar» a que el otro sistema se tenga que autenticar contra SharePoint no hace más que dar parte de razón a esos responsables de IT que comentaba anteriormente.
¿Como lo podemos solucionar?
El modelo de objetos de Servidor (SSOM) de SharePoint es muy completo, contiene una gran cantidad de utilidades y de operaciones. Casi todo lo que podemos hacer mediante código servidor y haciendo uso de Windows PowerShell para completar todas las posibilidades.
Seguro que a casi todos los desarrolladores de SharePoint conocen el «RunWithElevatedPrivileges», esta instrucción lo que hace es ejecutar diversos fragmentos de código como si fuéramos Administradores. Utilizando esta acción desde nuestro código podríamos realizar cualquier operación y poder integrarlo con cualquier sistema. Pero… claro es algo más que una burrada y una operación que no podemos ni debemos permitir.
Aunque esta claro el porqué, no está de más comentar una serie de aspectos para que se nos quite esta idea de la cabeza:
- Si ejecutamos todo con el SuperUsuario, permitimos hacer a los usuarios normales puedan ejecutar acciones que no tienen permisos. Ejemplo: consultar documentos/bibliotecas que no deben.
- El Performance de SharePoint a la hora de determinadas operaciones se puede alterar.
- La Gobernance del propio SharePoint estaría más propia de una república bananera que de un criterio profesional.
- Etc..
Para más aspectos no dudes de revisar la salud de tu SharePoint.
Cómo poder solucionarlo
Si analizamos un poco más el SSOM tenemos la opción de obtener un Token de usuario. Este Token es la identidad que tiene el usuario en SharePoint y todos los privilegios que tiene este usuario dentro de nuestra colección de sitio. Para obtener el Token de un usuario lo podemos realizar de una forma semejante a la siguiente:
using (var spSite = new SPSite(ConfigurationManager.AppSettings["Site"])) { using (var spWeb = spSite.OpenWeb()) { var spUser = spWeb.EnsureUser(domainUser); result = spUser.UserToken.BinaryToken; } }
Con el token obtenido podemos abrir un objeto SPSite con las credenciales del usuario en cuestión, para ello no hace falta más que el siguiente código:
var user= new SPUserToken(token); var site= new SPSite(url,user);
Añadiendo WebApi el SSOM
Todo lo comentado anteriormente, no son más que posibilidades que nos da el modelo de Objeto de Servidor de SharePoint. Ahora bien, ¿cómo lo podemos integrar con una Web API?. Desde Encamina para poder utilizar la WebAPI con otros Sistemas hemos establecido un protocolo para hacer uso de la misma. Para ello, antes de empezar a utilizar la WebAPI lo que hacemos es que nuestro cliente (llamamos a cliente a la Aplicación independiente de la plataforma) solicita el Token que lo tenemos en una acción de un Controlador. Por ejemplo:
public class LoginController : ApiController { [Route("api/login/{domain}/{user}")] [HttpPost] public IList<byte> GetToken(string domain,string user) { var domainUser = string.Concat(domain, "\\", user); byte[] result = null; SPSecurity.RunWithElevatedPrivileges(delegate { using (var spSite = new SPSite(ConfigurationManager.AppSettings["Site"])) { using (var spWeb = spSite.OpenWeb()) { spWeb.AllowUnsafeUpdates = true; var spUser = spWeb.EnsureUser(domainUser); result = spUser.UserToken.BinaryToken; spWeb.AllowUnsafeUpdates = false; } } }); return result.ToList(); } }
Una vez nuestro cliente tiene el Token, para poder utilizar cualquier otro Controlador de nuestra WebAPI lo que establecemos es que en la petición a dicho controlador debe de tener este Token en la Cabecera, en caso de que no lo tenga mediante un filtro que proporciona la WebAPi devolemos un error de petición no permitida.
La pregunta del millón: este sistema es seguro?
Partiendo de la base que todo sistema se puede vulnerar y tiene algún punto débil, ésta forma de extender las capacidades de SharePoint para hacer uso de herramientas actuales como puede ser la WebAPI 2, es bastante seguro, por varias razones:
- Tenemos la seguridad que pueda tener WebAPI (NTLM, Basic, Forms..)
- La seguridad que proporciona SharePoint
- El proceso de comunicación de SharePoint con la WebAPI
Conclusión
SharePoint no es un sistema cerrado como mucha gente piensa, quizás en sus primeras versiones era muy difícil su integración con otros sistemas, pero las dos últimas versiones y las novedades que se están anunciando en su plataforma Online, no hacen más que la posibilidad de integrar SharePoint con cualquier otra plataforma sea un hecho y algo bastante frecuente en nuestros desarrollos.