Compartir por


Limpieza del acceso heredado

En este artículo se presenta cómo quitar el acceso heredado para los registros cuando cambia la configuración en cascada de una tabla en Microsoft Dataverse.

Síntomas

Después de cambiar el comportamiento en cascada de una relación de tabla para la acción Reparent o Share a No Cascade, seguirá teniendo acceso a los registros relacionados que se deben quitar.

Los usuarios pueden informar de que tienen acceso inesperado a los registros. Hay dos maneras de comprobar el acceso a los registros relacionados: mediante la característica Comprobar acceso o el RetrieveAccessOrigin mensaje.

Uso de la característica Comprobar acceso

Use la característica Comprobar acceso en aplicaciones controladas por modelos para comprobar quién tiene acceso a un registro. Los administradores pueden usar esta característica para comprobar usuarios individuales o todos los usuarios que tienen acceso a un registro.

Al usar el comprobador de acceso, verá una lista de los motivos por los que un usuario tiene acceso. Algunos de estos motivos indican que se concedió el uso compartido debido al acceso a un registro relacionado. Por ejemplo:

  • El registro se compartió conmigo porque tengo acceso a registros relacionados.
  • El registro se ha compartido con los equipos de los que soy miembro porque el equipo tiene acceso a registros relacionados.

Uso del mensaje RetrieveAccessOrigin

Los desarrolladores pueden usar el RetrieveAccessOrigin mensaje para detectar qué usuarios tienen acceso a un registro. Este mensaje devuelve una frase que describe por qué el usuario tiene acceso. Cualquiera de los siguientes resultados indica que se concedió el acceso debido al uso compartido de un registro relacionado:

PrincipalId is owner of a parent entity of object (<record ID>)
PrincipalId is member of team (<team ID>) who is owner of a parent entity of object (<record ID>)
PrincipalId is member of organization (<organization ID>) who is owner of a parent entity of object (<record ID>)
PrincipalId has access to (<parent record ID>) through hierarchy security. (<parent record ID>) is owner of a parent entity of object (<record ID>)

Para obtener más información, vea Determinar por qué un usuario tiene acceso con código.

Causa

Cuando cambia el comportamiento en cascada de una relación de tabla, Dataverse inicia un trabajo asincrónico para quitar el acceso que se concedieron anteriormente a los usuarios. Sin embargo, este trabajo puede producir un error, lo que provoca que los usuarios conserven el acceso.

Solución

El primer paso para resolver este problema es volver a crear el trabajo del sistema para quitar el acceso. Si se produce un error en el trabajo, un desarrollador puede usar el ResetInheritedAccess mensaje para aplicar el cambio a un conjunto de registros especificado.

Volver a crear el trabajo del sistema para quitar el acceso

Los desarrolladores pueden usar el CreateAsyncJobToRevokeInheritedAccess mensaje para intentar volver a crear un trabajo asincrónico.

Use la clase Microsoft.Xrm.Sdk.Messages.CreateAsyncJobToRevokeInheritedAccessRequest.

/// <summary>
/// Creates and executes an asynchronous cleanup job to revoke inherited access granted through cascading inheritance.
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance to use.</param>
/// <param name="relationshipSchemaName">The schema name of the entity relationship.</param>
public static void CreateAsyncJobToRevokeInheritedAccessExample(IOrganizationService service, string relationshipSchemaName)
{
    var request = new Microsoft.Xrm.Sdk.Messages.CreateAsyncJobToRevokeInheritedAccessRequest()
    {
        RelationshipSchema = relationshipSchemaName
    };

    service.Execute(request);
}

Obtenga más información sobre el uso de mensajes con el SDK para .NET.

La CreateAsyncJobToRevokeInheritedAccess acción crea un nuevo trabajo asincrónico denominado RevokeInheritedAccess. Puede supervisar el éxito de este trabajo. Para obtener más información, consulte supervisión de trabajos del sistema o administración de trabajos del sistema con código.

Restablecimiento del acceso heredado

Si se produce un error al volver a crear el trabajo del sistema para quitar el acceso , un desarrollador con privilegios de administrador del sistema o personalizador del sistema puede usar el ResetInheritedAccess mensaje para dirigirse a un subconjunto de registros coincidentes. Es posible que tenga que usar este mensaje varias veces para quitar el acceso a todos los registros.

/// <summary>
/// Resets the inherited access for the matching records.
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance to use.</param>
/// <param name="fetchXml">The fetchxml query.</param>
public static void OutputResetInheritedAccess(IOrganizationService service, string fetchXml)
{
    var parameters = new ParameterCollection()
    {
        { "FetchXml", fetchXml}
    };

    var request = new OrganizationRequest()
    {
        RequestName = "ResetInheritedAccess",
        Parameters = parameters
    };

    var response = service.Execute(request);

    Console.WriteLine(response.Results["ResetInheritedAccessResponse"]);
}

Obtenga más información sobre el uso de mensajes con el SDK para .NET.

El ResetInheritedAccess mensaje intenta ejecutarse sincrónicamente cuando no hay muchos registros coincidentes. A continuación, el ResetInheritedAccessResponse valor termina con ExecutionMode : Sync. Si hay muchos registros coincidentes, la operación tarda más tiempo y el valor termina con ExecutionMode : Async. Se crea un trabajo del sistema denominado Denormalization_PrincipalObjectAccess_principalobjectaccess:<caller ID> y puede supervisar el éxito de ese trabajo. Para obtener más información, consulte supervisión de trabajos del sistema o administración de trabajos del sistema con código.

El ResetInheritedAccess mensaje requiere una consulta FetchXml para identificar los registros. Esta consulta debe cumplir los siguientes requisitos:

  • Use la principalobjectaccesstabla (POA).
  • Devuelve solo la principalobjectaccessid columna.
  • No debe incluir ningún link-entity elemento. No se puede agregar una combinación a otra tabla.
  • Filtre solo por las columnas de la principalobjectaccess tabla.

Esta tabla está disponible para la API web como tipo de entidad principalobjectaccess. No se incluye en la referencia de tabla o entidad de Dataverse porque la tabla POA no admite ningún tipo de operación de modificación directa de datos. Debe conocer las columnas de esta tabla para crear la consulta FetchXml.

Columnas de tabla poa

Debe crear una consulta FetchXml con solo estas columnas.

Nombre lógico Tipo Descripción
accessrightsmask Entero Contiene los valores combinados de miembros de enumeración AccessRights para los derechos de acceso que la entidad de seguridad tiene directamente.
changedon DateTime Última fecha en la que cambió el acceso de la entidad de seguridad al registro.
inheritedaccessrightsmask Entero Contiene los valores combinados de miembros de enumeración AccessRights para los derechos de acceso que se aplican debido a la herencia.
objectid Identificador único Identificador del registro al que tiene acceso la entidad de seguridad.
objecttypecode Entero Valor de EntityMetadata.ObjectTypeCode que corresponde a la tabla. Este valor no es necesariamente el mismo para diferentes entornos. Para las tablas personalizadas, se asigna en función del orden en que se creó la tabla. Para obtener este valor, es posible que tenga que ver los metadatos de la tabla. Hay varias herramientas de la comunidad para encontrar esto. Esta es una solución de Microsoft: Examinar definiciones de tabla en su entorno.
principalid Identificador único Identificador del usuario o equipo al que tiene acceso.
principalobjectaccessid Identificador único Clave principal de la tabla POA.
principaltypecode Entero Código de tipo de la entidad de seguridad. SystemUser = 8, Team = 9.

Los siguientes valores de miembro de enumeración AccessRights se aplican a las accessrightsmask columnas y inheritedaccessrightsmask :

Tipo de acceso Valor Descripción
None 0 Sin acceso.
Read 1 Derecho a leer un registro.
Write 2 Derecho a actualizar un registro.
Append 4 Derecho a anexar el registro especificado a otro registro.
AppendTo 16 Derecho a anexar otro registro al registro especificado.
Create 32 Derecho a crear un registro.
Delete 65,536 Derecho a eliminar un registro.
Share 262,144 Derecho a compartir un registro.
Assign 524,288 Derecho a asignar el registro especificado a otro usuario o equipo.

Es posible que vea que el inheritedaccessrightsmask valor suele ser 135 069 719. Este valor incluye todos los tipos de acceso excepto para Create, que no es necesario porque estos derechos solo se aplican a los registros ya creados.

Ejemplos de FetchXml

En esta sección se incluyen algunos ejemplos de consultas FetchXml que puede usar con el ResetInheritedAccess mensaje. Para obtener más información, consulte Uso de FetchXML para construir una consulta.

Restablecimiento del acceso heredado proporcionado a un usuario determinado para una cuenta específica
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="principalid" operator="eq" value="9b5f621b-584e-423f-99fd-4620bb00bf1f" />
            <condition attribute="objectid" operator="eq" value="B52B7A48-EAFB-ED11-884B-00224809B6C7" />
        </filter>
    </entity>
</fetch>
Restablecimiento del acceso heredado proporcionado a todas las filas secundarias para un tipo de objeto especificado
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="objecttypecode" operator="eq" value="10042" />
        </filter>
    </entity>
</fetch>
Restablecimiento del acceso heredado proporcionado a un usuario especificado para todos los tipos de objeto
<fetch>
    <entity name="principalobjectaccess">
        <attribute name="principalobjectaccessid"/>
        <filter type="and">
            <condition attribute="principalid" operator="eq" value="9b5f621b-584e-423f-99fd-4620bb00bf1f" />
        </filter>
    </entity>
</fetch>