Aunque los Manejadores de Eventos existen en SharePoint desde su versión 2007, en SharePoint 2013 se introdujo una categoría totalmente nueva: los Manejadores de Eventos de Seguridad. La detección de estos eventos permiten iniciar acciones cuando se modifica la configuración de derechos: la herencia de permisos se ha roto o restituido, se han modificado los grupos de seguridad o los niveles de permisos, o se han modificado los usuarios que pueden interactuar con el sistema.
Seguridad dentro de SharePoint
SharePoint utiliza un modelo de seguridad que es, al mismo tiempo, poderoso, flexible y fácil de entender y mantener mientras se observen algunas reglas básicas de gobernabilidad. En principio, la misma configuración de seguridad se mantiene y hereda desde el nivel superior de estructura visible a los usuarios, la Colección de Sitios, hasta el nivel más básico, los elementos de Listas y los documentos de Bibliotecas. Esto significa que los grupos de seguridad definidos en el sitio de nivel superior de cualquier Colección de Sitios son transmitidos automáticamente cuando se crea cualquier objeto debajo de ella (sub-Sitios, Listas, Bibliotecas, elementos, documentos), y cuando se modifica la estructura de seguridad en el nivel más alto, los niveles más bajos reciben los cambios automáticamente y sin necesidad de que los usuarios o administradores realicen ninguna acción.
La estructura de la autorización dentro de SharePoint se basa en algunos objetos sencillos de entender y manejar:
1 - Permisos - SharePoint define una serie de Permisos por defecto que incluyen prácticamente todas las actividades de base que se pueden realizar en el sistema: "Agregar elementos", "Eliminar elementos", "Crear subsitios", "Administrar alertas", etc. SharePoint Foundation y Server disponen de 33 tipos de permisos divididos en tres secciones, y no es posible crear ni agregar nuevos tipos fuera de los por defecto
2 - Niveles de Permisos - Los Permisos se pueden agrupar en "Niveles de Permisos". Cada Nivel permite definir que Permisos son aceptados y cuáles no. Por ejemplo, un Nivel de Permisos permite "Administrar Listas", "Agregar elementos", etc. (como en el Nivel de Permisos llamado "Editar" en un Sitio de Colaboración), mientras que otro Nivel permite solamente "Ver elementos" y 'Ver versiones" (como el Nivel de "Solo vista" de la misma plantilla). Los Niveles de Permisos se pueden configurar y/o crear desde la página Administración de un Sitio yendo a "Permisos del sitio" - "Niveles de permisos", y cada plantilla para crear Sitios (o Colecciones de Sitios) crea su propia estructura en el momento de aprovisionamiento
3 - Grupos de Seguridad - Es el contenedor que permite asignar un determinado grupo de Permisos (un Nivel de Permisos) a un determinado grupo de usuarios. Normalmente a un Grupo de Seguridad se le asocian Grupos de Usuarios del Directorio Activo o usuarios individuales. Un Grupo de Seguridad utiliza un solo Nivel de Permisos, pero un Nivel de Permisos puede ser utilizado por diferentes Grupos de Seguridad. SharePoint permite definir un máximo de 50.000 Grupos de Seguridad para una Lista, aunque Microsoft recomienda no utilizar más de 5.000 para no afectar el rendimiento del sistema.
El mecanismo de "Herencia" asegura que la estructura creada en un nivel superior sea legada a los niveles inferiores. De esta forma, cuando, por ejemplo, se crea un Grupo de Seguridad en el Sitio de nivel superior de una Colección de Sitios, todos los Sitios, Listas y elementos creados posteriormente tendrán la misma estructura de derechos; y cuando se modifica a nivel de Colección de Sitios, todos los artefactos debajo de ella reconocen de inmediato y automáticamente los cambios.
SharePoint, para flexibilizar la estructura de derechos, permite "romper la Herencia" en cualquiera de sus artefactos. Por ejemplo, para hacer que una Lista tenga permisos diferentes que el Sitio en donde reside, es posible ir desde la página de administración de la Lista a "Configuración de la lista" - "Permisos para esta lista" y utilizar el botón de "Dejar de heredar permisos" en el menú de Cinta. Desde este momento, aunque los grupos iniciales todavía existen en la Lista, es posible eliminarlos y/o crear nuevos que utilicen Niveles de Permisos propios. De la misma forma, en un artefacto de SharePoint en donde se ha roto la Herencia es posible utilizar el botón de "Eliminar permisos exclusivos" para reestablecer la Herencia (en cuyo caso los permisos individuales son eliminados automáticamente).
Aunque esta estructura asegura una gran flexibilidad para configurar los derechos dentro de SharePoint, también existe el riesgo de que si no se toman algunas medidas, la organización se convierta en caos, haciendo el trabajo de mantenimiento del sistema muy difícil y, por lo tanto, muy costoso. Para evitar el caos, solamente es necesario tomar un par de medidas de gobierno:
1 - Evite romper la Herencia lo más posible. Si los derechos están manejados única y exclusivamente desde el nivel superior de la Colección de Sitios, es posible mantener el control sobre que usuarios tienes acceso a cual información
2 - Evite acoplar usuarios individuales a Grupos de Seguridad de SharePoint. En lugar de ello, cree grupos de Directorio Activo y acople los grupos de AD a los Grupos de Seguridad de SharePoint. Esto permite manejar los derechos de los usuarios a un nivel empresarial (el AD de la compañía) en lugar de a nivel local en SharePoint
3 - Nunca asigne un Nivel de Permisos directamente a usuarios o Grupos de AD por fuera de uno de los Grupos de Seguridad de SharePoint. Aunque se puede hacer en SharePoint, es la forma más fácil de crear caos y perder totalmente el control sobre la seguridad del sistema
Manejadores de Eventos en SharePoint
SharePoint dispone de un sistema para detectar cambios en sus objetos, dando la oportunidad de crear software que reaccione a los cambios. Por ejemplo, es posible detectar cuando un nuevo documento es agregado a una Biblioteca, y crear software que envíe un Email o valide el nombre utilizado. Este sistema se denomina un "Manejador de Eventos".
Desde las versiones anteriores de SharePoint existen Manejadores de Eventos para Elementos y Documentos (clase SPItemEventReceiver), Listas y Bibliotecas (clase SPListEventReceiver), Sitios y Colecciones de Sitios (clase SPWebEventReceiver), Flujos de Trabajo (clase SPWorkflowEventreceiver) e Emails (clase SPEmailEventReceiver). Los Manejadores están divididos a su vez en dos tipos principales:
Visual Estudio, la herramienta por defecto para programar para SharePoint, dispone de plantillas con sus respectivos asistentes para crear Manejadores de Eventos. Básicamente, un Manejador de Eventos para SharePoint 2013 es una biblioteca de clases de código manejado en .NET Framework 4.5 utilizando CSharp o Visual Basic, que genera una dll que puede ser instalada utilizando una Solución de SharePoint (archivo .wsp) y su respectiva Característica para activarla/desactivarla.
Manejadores de Eventos de Seguridad en SharePoint 2013
SharePoint 2013 introduce un nuevo tipo de Manejadores de Eventos a los ya existentes en versiones anteriores: los que detectan cuando se ha modificado algo en el esquema de permisos (clase SPSecurityEventReceiver).
Correspondiendo con la estructura de seguridad de SharePoint descrita al principio del artículo, los 24 nuevos Eventos reaccionan a las acciones que se pueden tomar al crear o modificar el esquema de seguridad:
La clase SPSecurityEventReceiver se puede utilizar tanto en SharePoint Server como en Foundation.
Programación de Manejadores de Eventos de Seguridad
A diferencia con la programación de los Manejadores de Eventos tradicionales de SharePoint, ni Visual Studio 2012 ni 2013 disponen de plantillas o asistentes para la programación de Manejadores de Eventos de Seguridad.
Para programar un Evento de Seguridad, utilice Visual Studio 2012 o 2013 siguiendo los pasos que se indican a continuación:
Reemplace todo el código generado automáticamente por el siguiente:
1using System;2
1using Microsoft.SharePoint;2
12
1namespace EventosSeguridad2
1{2
1 public class MisEventosSeguridad : SPSecurityEventReceiver2
1 {2
1 public override void GroupUserAdded(SPSecurityEventProperties properties)2
1 {2
1 base.GroupUserAdded(properties);2
12
1 SPUser usuarioAgregado = properties.Web.AllUsers.GetByID(properties.GroupUserId);2
1 SPGroup grupoAgregado = properties.Web.Groups.GetByID(properties.GroupId);2
1 string myMensaje = "GroupUserAdded - " + usuarioAgregado.LoginName + " - " + grupoAgregado.Name;2
1 WriteToFile(myMensaje);2
1 }2
12
1 private void WriteToFile(string myMensaje)2
1 {2
1 using (System.IO.StreamWriter myFile = new System.IO.StreamWriter(@"C:\EventosSeguridad.txt", true))2
1 {2
1 myFile.WriteLine(DateTime.Now.ToString() + " - " + myMensaje);2
1 }2
1 }2
1 }2
1}2
Note que la clase hereda de "SPSecurityEventReceiver". Dentro de la clase se ha creado inicialmente un método que sobrescribe a "GroupUserAdded", lo que significa que el código dentro del método se va a ejecutar cuando se agrega usuarios a un Grupo de Seguridad. El código utiliza el parámetro de "properties" para crear objetos que contienen la información tanto del usuario como del Grupo agregados. Finalmente se hace una llamada a un método auxiliar que simplemente agrega un mensaje en un archivo de texto (que se crea automáticamente si no existe).
1public class InstalarEventosSeguridadEventReceiver : SPFeatureReceiver2
1 {2
1 public override void FeatureActivated(SPFeatureReceiverProperties properties)2
1 {2
1 SPWeb myWeb = properties.Feature.Parent as SPWeb;2
1 SPEventReceiverDefinition definicionGroupUserAdded = myWeb.EventReceivers.Add();2
1 definicionGroupUserAdded.Name = "Manejador Evento GroupUserAdded";2
1 definicionGroupUserAdded.Type = SPEventReceiverType.GroupUserAdded;2
1 definicionGroupUserAdded.Assembly = Assembly.GetExecutingAssembly().FullName;2
1 definicionGroupUserAdded.Class = "EventosSeguridad.MisEventosSeguridad";2
1 definicionGroupUserAdded.Update();2
1 myWeb.Update();2
1 }2
12
1 public override void FeatureDeactivating(SPFeatureReceiverProperties properties)2
1 {2
1 SPWeb myWeb = properties.Feature.Parent as SPWeb;2
12
1 foreach (SPEventReceiverDefinition eventReceiver in myWeb.EventReceivers)2
1 {2
1 if (eventReceiver.Name.Equals("Manejador Evento GroupUserAdded"))2
1 {2
1 eventReceiver.Delete();2
1 break;2
1 }2
1 }2
1 }2
Aquí se están utilizando dos eventos de la Característica:
Importante en la activación es que el Evento de Seguridad se registra a nivel de Sitio (SPWeb), el único objeto de SharePoint que acepta este tipo de Manejadores (no es posible activarlos a nivel de Lista o de Colección de Sitios).
1. Compile y despliegue el proyecto. Vaya a una Lista o Biblioteca, abra su página de configuración y utilice el vínculo de "Permisos para esta biblioteca de documentos" (o "esta lista"). Seleccione uno de los Grupos de Seguridad y agréguele un usuario. Revise el archivo que el Manejador de Eventos crea ("C:\EventosSeguridad.txt"), el que debe contener una entrada del tipo:
[fecha][hora] - GroupUserAdded - i:0#.w|[dominio][usuario] - [Grupo Seguridad]
También revise que en la página de Configuración del Sitio - "Administrar las características del sitio" se encuentra la Característica "EventosSeguridad Feature1" y que está activada.
2. Desactive la Característica mencionada en el punto anterior (lo que debe eliminar el Manejador de Eventos creado). Repita los pasos enumerados en el punto 10 para agregar otro usuario y revise que no existe una nueva entrada en el archivo.
3. En el código de ejemplo del Manejador de Eventos de Seguridad (punto 4) se muestra solamente como utilizar el evento de "GroupUserAdded", pero cualquiera de los eventos de la clase SPSecurityEventReceiver puede ser sobrescrito exactamente de la misma forma, y utilizando el mismo parámetro de entrada "SPSecurityEventProperty". A su vez, para instalar cualquier Manejador no es necesario más que crear un nuevo objeto del tipo "SPEventReceiverDefinition", asignarle un nombre único, definir su tipo, ensamblado y clase y añadirlo a la colección de eventos de la clase SPWeb. Para desinstalarlo se puede utilizar el nombre que se utilizó para su creación y removerlo de la colección de eventos de la misma forma que se ha indicado en el punto 9.
4. Como se describió en el punto 4, existen varias formas para registrar el Manejador de Eventos de Seguridad. Fuera de utilizar una Característica es posible utilizar también scripts de PowerShell de SharePoint. El siguiente script registra el Manejador después de que ha sido instalado utilizando su Solución .wsp de SharePoint:
1$myWeb = Get-SPWeb -Identity "http://servidor"2
1$definicionGroupUserAdded = $myWeb.EventReceivers.Add()2
1$definicionGroupUserAdded.Name = "Manejador Evento GroupUserAdded"2
1$definicionGroupUserAdded.Type = [Microsoft.SharePoint.SPEventReceiverType]::GroupUserAdded2
1$definicionGroupUserAdded.Assembly = "EventosSeguridad, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8413486149d08dcb"2
1$definicionGroupUserAdded.Class = EventosSeguridad.MisEventosSeguridad"2
1$definicionGroupUserAdded.Update()2
Substituya los valores necesarios para la identidad del Sitio SPWeb y el nombre, tipo, ensamblado y clase de la definición. Se tiene que utilizar el nombre completo del ensamblado en la propiedad "Assembly", incluyendo su token público.
Para desinstalarlo se puede utilizar un script de PowerShell de SharePoint similar al siguiente:
1foreach ($unManejador in $myWeb.EventReceivers)2
1{ if ($unManejador.Name.Equals("Manejador Evento GroupUserAdded"))2
1{ $unManejador.Delete() } }2
Problemas con los Manejadores de Eventos de Seguridad
Aunque los Manejadores de Eventos de Seguridad funcionan perfectamente y pueden ser programados fácilmente como se ha indicado, presentan dos problemas que es importante tener en cuenta cuando se está diseñando su uso.
Conclusión
SharePoint 2013 incluye la clase necesaria para detectar eventos que ocurren cuando se modifica la estructura de seguridad del sistema, algo que no existía en las versiones anteriores del producto. Desafortunadamente Visual Studio no incluye plantillas para la creación de Manejadores de eventos de Seguridad, pero eso no significa que no sea posible (ni difícil) crearlos. También existen algunas limitaciones de los eventos, las que hay que tener muy en cuenta cuando se están diseñando sistemas que los utilizan.
Gustavo Velez MVP SharePoint gustavo@gavd.net http://www.gavd.net