Asignar permisos únicos a elementos en listas de SharePoint via API

¡Muy buenas!

Ya tocaba empezar a actualizar el blog con contenido M365 y esta primera entrada no es casual. Los espacios de colaboración de SharePoint son utilizados de mil modos distintos por organizaciones de todo el mundo, tanto por usuarios internos a la organización como externos.

Un escenario que curiosamente me he encontrado muchas veces es la colaboración en listas o bibliotecas de documentos donde un grupo de usuarios tiene acceso, pero no todos los usuarios deben tener los mismos permisos sobre la lista. Entonces se plantea solución rápida: rompemos herencia de permisos respecto al sitio y asignamos por grupo de usuarios qué permisos les pertenecen sobre la lista (editar, leer, control total...).
Pero no, el caso es un poco más complejo: necesitamos que algunos usuarios tengan, por ejemplo, permisos de lectura solo sobre algunos elementos de la lista; o que un grupo de usuarios solo pueda editar sus propios elementos. Vamos a ver qué soluciones tenemos:

Solución 1 - vía configuración de la lista

En este caso SharePoint nos lo pone bastante fácil a nivel de configuración de la lista podemos resolver el escenario cuando los usuarios están creado ellos mismos, manualmente, los elementos:

  • Vamos a List Settings -> Advanced Settings y ahí encontramos el apartado "Item-level permissions"
  • Vemos que tenemos la opción de asignar permisos únicos de lectura o escritura para los elementos. La propia configuración es bastante clara: podemos limitar que solo el usuario que ha creado el elemento pueda verlo y editarlo.
Hay que tener algo claro: 


Esta limitación de permisos solo se aplica a usuarios con permisos "Colaborar" y "Editar", es decir que si el usuario tiene "Diseño" o "Control total" sobre la lista, esta configuración de permisos únicos no funcionará para estos usuarios. ¡Importante tenerlo en cuenta!

Pero a todo esto... ¿y qué sucede si una aplicación externa está creando los elementos?

Solución 2 - asignación de permisos únicos por HTTP


Sinceramente esta es la solución que ha resuelto el 80% de mis escenarios, pero creo que también era importante entender la Solución 1 y sus limitaciones. Podemos atacar la API de SharePoint para romper la herencia de permisos que recibe el elemento de la propia lista y asignar nuevos permisos. Esta solución es muy práctica cuando desarrollamos soluciones en Power Automate, Logic Apps, Azure Functions, etc.

Sabéis que no me gusta dejar ni un cabo suelto, así que intentaré que sea lo más completo posible. Para ello he decidido mostrarlo como se hace en Power Automate, se verá más esquemático y bonito que en varias líneas de llamadas HTTP.

Primero aclarar que si bien podríamos trabajar con usuarios individuales, me gusta asignar los permisos por grupos (aunque sea un grupo de una persona). Se hace más entendible añadir permisos a grupos específicos, que a usuarios (que si perdemos el usuario en la plataforma, deberemos retocar los permisos). Pero eso ya dependerá del escenario y vuestras preferencias.

Entonces supongamos que tenemos el grupo "Estudiantes", podemos hacer una llamada a la API de SharePoint para recuperar la ID del grupo o tenerla ya preguardada en una variable. Así sería la llamada:


Una llamada a la API de SharePoint con un pequeño filtro por nombre. Así obtenemos las propiedades de vuelta, entre ellos la ID: 27.

Entonces vamos a proceder rompiendo la herencia de permisos del elemento de la lista, podemos hacerlo de dos modos: o dejamos los roles por defecto de la lista, o lo rompemos sin ningún tipo de permiso asignado al elemento (solo los site collection admins van a poder gestionarlo).

Se hace con la partícula copyRoleAssignments, "true" para mantener de base los permisos de la lista, o "false" para borrarlos. Soy bastante fan del segundo, facilita bastante y deja claro de dónde partimos.



A partir de aquí deberemos asignar los permisos a cada grupo que queramos. Recuerdo que los administradores de la colección de sitios siempre podrán verlo, pero por si acaso tuviéramos otros grupos intermedios como "agentes" que pudiesen ver también todos los elementos, habría que añadirles los permisos también.

Necesitamos la ID de rol de permisos a parte de la ID de grupo, esta ID acostumbran a ser únicas para permisos por defecto (Leer, Contribuir, Control total...), pero no está de más hacer una llamadita a la API de SharePoint para saber la ID exacta del rol de permisos. Podemos hacerlo con Power Automate o como he dicho antes, tenerlo preguardado en una variable.

La url es: https://[sitio SharePoint]/_api/web/RoleDefinitions




Efectivamente puedo ver que la ID para solo una lectura del elemento (recomendaría añadir el de Editar, pero esto solo es un ejemplo) es 1073741826.

Entonces solo nos queda lanzar una petición a SharePoint con estos valores donde principalid es la ID del grupo al que quiero dar permisos y roleDefId es la ID de rol de permisos que hemos extraído en último paso.



Pues en principio ya está :) Hemos roto la herencia de permisos, hemos asignado permisos únicos y ahora cada usuario tiene sus propios permisos para cada elemento de la lista.

No dudéis en preguntarme lo que sea, este tema daría para una tesis en SharePoint jejeje recuerdo que cuando trabajamos con permisos únicos podemos caer en escenarios tan pintorescos como el de Acceso Limitado ;)





5 Comentarios

  1. Buenas tardes,
    Me ha resultado muy interesante el articulo.
    Tengo un escenario parecio al que no consigo darle forma, te explico...
    En una lista de Sharepoint tengo una columna donde seleccionamos un usuario de Office365, necesito que ese usuario que seleccionamos solo tenga acceso para ver los registros donde se le haya agregado, el resto de registros no tiene que verlos.
    Me gustaria que ese cambio de permisos se realizase automaticamente cuando se agrega el usuario a la columna en cuestion.
    Muchas gracias

    ResponderEliminar
  2. Buenos días Pedro,
    entiendo perfectamente el caso de uso, a ver si puedo ayudarte. Te describo los pasos que yo seguiría:
    - Primero un flujo de Power Automate con el desencadenante "cuando el elemento se modifique", para detectar cuando esa columna se ha modificado.
    - Romper herencia del elemento sin heredar permisos del padre (empezar "de cero").
    - Seguidamente tendrás que recuperar la ID de usuario SharePoint del usuario en cuestión (atención! la id es distinta en cada sitio SharePoint). Para hacerlo, en vez de consultarla API de SiteGroups, deberás hacer una petición HTTP al endpoint de SiteUsers "/_api/web/SiteUsers" con el filtro ?$filter= Title eq 'aquí display name del usuario'

    - Una vez tengas la id del usuario, todo lo demás es igual, en principalid en el método addroleassignment en este caso sería el del usuario

    :) Y voilà, tenemos para cada elemento, los permisos únicos que le corresponden según el usuario.

    ResponderEliminar
  3. Buenas.
    Este artículo me ha gustado mucho. Me ha enseñado un mundo que no conocía y que tengo que investigar mas a fondo.

    Tengo una duda.
    Configuras una lista para que un usuario "sólo" puedan ver los elementos de lista que el ha creado.

    Pero por cualquier razón ese usuario se va, o quieres que sean mas usuarios los que vean esos elementos de lista.

    Como se cambian los permisos de un elemento ya creado para darle permisos a otro usuario.

    No se si se entiende lo que digo.

    Veo 400 elementos que yo he creado. Pero también creo que los veo algún otro usuario específico que no tenga "control total".

    Un saludo y gracias.

    ResponderEliminar
  4. Hola javi! Muchísimas gracias por tu comentario!
    Por supuesto, podemos obtener esos objetos de nuevo con un Get Items, en vez de hacer un addroleassignments, utilizamos el tipo DELETE a la llamada a la API sobre el roleassignments y el elemento en concreto.
    Otro modo más complicado sería hacer un get sobre el roleassignments y filtrando por el código del usuario que comentas, luego para cada uno de estos elementos entonces hacer el DELETE de la asignación de permisos.
    Por supuesto después deberías añadirle los nuevos permisos.

    Y por último, como bien comentas, los usuarios con Control Total sobre la lista SIEMPRE van a poder ver todos los elementos, son super usuarios y es un procedimiento habitual.

    ¡Gracias y me comentas!

    ResponderEliminar
  5. Hola María del Mar, un gusto saludarte. no se si aún estás respondiendo al tema pero igual te hago la pregunta.

    Tengo una lista, donde manejo un flujo de aprobación. El usuario que crea el elemento en la lista solo puede ver los elementos que el mismo ha creado.

    En esta lista tengo una columna [APRPBADOR] donde el usuario asigna a la persona que va a hacer la aprobación, mediante un flujo al cambiar el valor de la columna [ESTADO] por el propietario de la lista, se envía la solicitud de aprobación al Aprobador.

    Como hago para que el aprobador pueda ver el elemento de la lista que está aprobando, ya que al estar limitado a que solo el usuario que creo el elemento de lista lo pueda ver, el aprobador no puede ver lo que va a aprobar.

    Quedo a espera de tus comentarios.

    ResponderEliminar