상속된 액세스를 정리하는 방법
이 문서에서는 Microsoft Dataverse에서 테이블의 계단식 구성이 변경될 때 레코드에 대한 상속된 액세스를 제거하는 방법을 소개합니다.
증상
재부모 또는 공유 작업에 대한 테이블 관계의 연속 동작이 No Cascade로 변경된 후에도 제거해야 하는 관련 레코드에 계속 액세스할 수 있습니다.
관련 레코드에 대한 액세스를 확인하는 방법
사용자는 레코드에 예기치 않은 액세스 권한이 있다고 보고할 수 있습니다. 액세스 확인 기능 또는 RetrieveAccessOrigin
메시지를 사용하여 관련 레코드에 대한 액세스를 확인할 수 있는 두 가지 방법이 있습니다.
액세스 확인 기능 사용
모델 기반 앱에서 액세스 확인 기능을 사용하여 레코드에 대한 액세스 권한이 있는 사용자를 확인합니다. 관리자는 이 기능을 사용하여 레코드에 액세스할 수 있는 개별 사용자 또는 모든 사용자를 확인할 수 있습니다.
액세스 검사기를 사용하는 경우 사용자에게 액세스 권한이 있는 이유 목록이 표시됩니다. 이러한 이유 중 일부는 관련 레코드에 대한 액세스로 인해 공유가 부여되었음을 나타냅니다. 예시:
- 관련 레코드에 액세스할 수 있으므로 레코드가 나와 공유되었습니다.
- 팀이 관련 레코드에 액세스할 수 있기 때문에 내가 구성원인 팀과 레코드를 공유했습니다.
RetrieveAccessOrigin 메시지 사용
개발자는 이 메시지를 사용하여 RetrieveAccessOrigin
레코드에 액세스할 수 있는 사용자를 검색할 수 있습니다. 이 메시지는 사용자에게 액세스 권한이 있는 이유를 설명하는 문장을 반환합니다. 다음 결과 중에서 관련 레코드 공유로 인해 액세스 권한이 부여되었음을 나타냅니다.
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>)
자세한 내용은 사용자가 코드를 사용하여 액세스할 수 있는 이유 확인(Determine)을 참조하세요.
원인
테이블 관계에 대한 연속 동작이 변경되면 Dataverse는 이전에 부여된 액세스 사용자를 제거하는 비동기 작업을 시작합니다. 그러나 이 작업이 실패하면 사용자가 액세스 권한을 유지할 수 있습니다.
해결
이 문제를 해결하는 첫 번째 단계는 시스템 작업을 다시 만들어 액세스를 제거하는 것입니다. 작업이 실패하면 개발자는 메시지를 사용하여 ResetInheritedAccess
지정된 레코드 집합에 변경 사항을 적용할 수 있습니다.
시스템 작업을 다시 만들어 액세스 제거
개발자는 메시지를 CreateAsyncJobToRevokeInheritedAccess
사용하여 비동기 작업을 다시 만들 수 있습니다.
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);
}
.NET용 SDK에서 메시지를 사용하는 방법에 대해 자세히 알아봅니다.
이 CreateAsyncJobToRevokeInheritedAccess
작업은 명명 RevokeInheritedAccess
된 새 비동기 작업을 만듭니다. 이 작업의 성공을 모니터링할 수 있습니다. 자세한 내용은 시스템 작업 모니터링 또는 코드로 시스템 작업 관리를 참조하세요.
상속된 액세스 다시 설정
시스템 작업을 다시 만들어 액세스를 제거하는 데 실패하면 시스템 관리자 또는 시스템 사용자 지정자 권한이 있는 개발자가 메시지를 사용하여 ResetInheritedAccess
일치하는 레코드의 하위 집합을 대상으로 지정할 수 있습니다. 모든 레코드에 대한 액세스를 제거하려면 이 메시지를 여러 번 사용해야 할 수 있습니다.
/// <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"]);
}
.NET용 SDK에서 메시지를 사용하는 방법에 대해 자세히 알아봅니다.
ResetInheritedAccess
일치하는 레코드가 많지 않은 경우 메시지는 동기적으로 실행하려고 합니다. 그런 다음 값은 ResetInheritedAccessResponse
.로 ExecutionMode : Sync
끝납니다. 일치하는 레코드가 많으면 작업이 더 오래 걸리고 값은 .로 ExecutionMode : Async
끝납니다. 이름이 지정된 Denormalization_PrincipalObjectAccess_principalobjectaccess:<caller ID>
시스템 작업이 만들어지고 해당 작업의 성공을 모니터링할 수 있습니다. 자세한 내용은 시스템 작업 모니터링 또는 코드로 시스템 작업 관리를 참조하세요.
메시지를 ResetInheritedAccess
사용하려면 레코드를 식별하기 위해 FetchXml 쿼리가 필요합니다. 이 쿼리는 다음 요구 사항을 충족해야 합니다.
principalobjectaccess
POA(테이블)를 사용합니다.- 열만 반환합니다
principalobjectaccessid
. - 요소를 포함하지
link-entity
않아야 합니다. 다른 테이블에 조인을 추가할 수 없습니다. - 테이블의 열만 필터링합니다
principalobjectaccess
.
이 테이블은 Principalobjectaccess 엔터티 형식으로 Web API에서 사용할 수 있습니다. POA 테이블은 모든 종류의 직접 데이터 수정 작업을 지원하지 않으므로 Dataverse 테이블/엔터티 참조에 포함되지 않습니다. FetchXml 쿼리를 작성하려면 이 테이블의 열을 알아야 합니다.
POA 테이블 열
이러한 열만 사용하여 FetchXml 쿼리를 작성해야 합니다.
논리적 이름 | Type | 설명 |
---|---|---|
accessrightsmask |
정수 | 보안 주체가 직접 가지고 있는 액세스 권한에 대한 결합된 AccessRights 열거 형 멤버 값을 포함합니다. |
changedon |
DateTime | 레코드에 대한 보안 주체의 액세스가 변경된 마지막 날짜입니다. |
inheritedaccessrightsmask |
정수 | 상속으로 인해 적용되는 액세스 권한에 대한 결합된 AccessRights 열거 형 멤버 값을 포함합니다. |
objectid |
고유 식별자 | 보안 주체가 액세스할 수 있는 레코드의 ID입니다. |
objecttypecode |
정수 | 테이블에 해당하는 EntityMetadata.ObjectTypeCode 값입니다. 이 값이 다른 환경에서 반드시 동일하지는 않습니다. 사용자 지정 테이블의 경우 테이블이 만들어진 순서에 따라 할당됩니다. 이 값을 얻으려면 테이블의 메타데이터를 확인해야 할 수 있습니다. 이를 찾기 위한 몇 가지 커뮤니티 도구가 있습니다. Microsoft의 솔루션 은 다음과 같습니다. 사용자 환경에서 테이블 정의를 찾아봅니다. |
principalid |
고유 식별자 | 액세스 권한이 있는 사용자 또는 팀의 ID입니다. |
principalobjectaccessid |
고유 식별자 | POA 테이블의 기본 키입니다. |
principaltypecode |
정수 | 보안 주체의 형식 코드입니다. SystemUser = 8, Team = 9. |
다음 AccessRights 열거 형 멤버 값은 열에 accessrightsmask
inheritedaccessrightsmask
적용됩니다.
액세스 형식 | 값 | 설명 |
---|---|---|
None |
0 | 액세스 권한이 없습니다. |
Read |
1 | 레코드를 읽을 수 있는 권한입니다. |
Write |
2 | 레코드를 업데이트할 수 있는 권한입니다. |
Append |
4 | 지정된 레코드를 다른 레코드에 추가할 수 있는 권한입니다. |
AppendTo |
16 | 지정된 레코드에 다른 레코드를 추가할 수 있는 권한입니다. |
Create |
32 | 레코드를 만들 수 있는 권한입니다. |
Delete |
65,536 | 레코드를 삭제할 수 있는 권한입니다. |
Share |
262,144 | 레코드를 공유할 수 있는 권한입니다. |
Assign |
524,288 | 지정된 레코드를 다른 사용자 또는 팀에 할당할 수 있는 권한입니다. |
이 값은 일반적으로 135,069,719임을 알 inheritedaccessrightsmask
수 있습니다. 이 값에는 이미 생성된 레코드에 Create
만 적용되므로 필요하지 않은 액세스 형식을 제외한 모든 액세스 형식이 포함됩니다.
FetchXml 예제
이 섹션에는 메시지와 함께 사용할 수 있는 FetchXml 쿼리의 몇 가지 예가 ResetInheritedAccess
포함되어 있습니다. 자세한 내용은 FetchXML을 사용하여 쿼리를 생성합니다.
특정 계정에 대해 특정 사용자에게 지정된 상속된 액세스 다시 설정
<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>
지정된 개체 형식에 대해 모든 자식 행에 지정된 상속된 액세스 다시 설정
<fetch>
<entity name="principalobjectaccess">
<attribute name="principalobjectaccessid"/>
<filter type="and">
<condition attribute="objecttypecode" operator="eq" value="10042" />
</filter>
</entity>
</fetch>
모든 개체 형식에 대해 지정된 사용자에게 지정된 상속된 액세스 다시 설정
<fetch>
<entity name="principalobjectaccess">
<attribute name="principalobjectaccessid"/>
<filter type="and">
<condition attribute="principalid" operator="eq" value="9b5f621b-584e-423f-99fd-4620bb00bf1f" />
</filter>
</entity>
</fetch>