다음을 통해 공유


MAzure Active Directory를 사용하여 Azure AI Search 결과를 트리밍하기 위한 보안 필터

이 문서에서는 Azure AI Search의 필터와 함께 보안 ID를 사용하여 사용자 그룹 멤버 자격에 따라 검색 결과를 자르는 방법을 보여 줍니다.

이 문서에서 다루는 작업은 다음과 같습니다.

  • 그룹 및 사용자 만들기
  • 만든 그룹과 사용자 연결
  • 새 그룹 캐시
  • 연결된 그룹을 사용하여 문서 인덱싱
  • 그룹 식별자 필터를 사용하여 검색 요청 실행

필수 조건

Azure AI 검색의 인덱스에는 문서에 대한 읽기 권한이 있는 그룹 ID 목록을 저장하는 보안 필드가 있어야 합니다. 이 사용 사례에서는 보안 개체 항목(예: 개인의 대학 지원서) 및 해당 항목에 대한 액세스 권한이 있는 사람을 지정하는 보안 필드(입학 담당자) 간의 일대일 대응을 가정합니다.

사용자, 그룹 및 연결을 만들려면 테넌트 관리자 권한(소유자 또는 관리자)이 있어야 합니다.

다음 절차에 설명된 대로 애플리케이션을 다중 테넌트 앱으로 등록해야 합니다.

Azure Active Directory에 애플리케이션 등록

이 단계에서는 사용자 및 그룹 계정의 로그인을 수락하기 위해 애플리케이션을 Azure Active Directory와 통합합니다. 조직의 테넌트 관리자가 아닌 경우 다음 단계를 수행하려면 새 테넌트를 생성해야 할 수 있습니다.

  1. Azure Portal에서 Azure Active Directory 테넌트 찾기

  2. 왼쪽의 관리에서 앱 등록을 선택한 다음 새 등록을 선택하세요.

  3. 검색 애플리케이션 이름과 유사한 이름으로 등록 이름을 지정하세요. 다른 선택적 속성에 대한 자세한 내용은 이 문서를 참조하세요.

  4. 등록을 선택합니다.

  5. 앱 등록을 생성하면 애플리케이션 (클라이언트) ID를 복사하세요. 애플리케이션에 이 문자열을 제공해야 합니다.

    DotNetHowToSecurityTrimming을 단계적으로 진행하는 경우, 이 값을 app.config 파일에 붙여넣으세요.

  6. 디렉터리(테넌트) ID를 복사합니다.

  7. 왼쪽에서 API 사용 권한을 선택한 다음 사용 권한 추가를 선택하세요.

  8. Microsoft Graph를 선택한 다음 위임된 권한을 선택하세요.

  9. 다음 위임된 권한을 검색한 다음 추가하세요.

    • Directory.ReadWrite.All
    • Group.ReadWrite.All
    • User.ReadWrite.All

    Microsoft Graph는 REST API를 통해 Azure Active Directory에 프로그래밍 방식으로 액세스할 수 있는 API를 제공합니다. 이 연습의 코드 샘플에서는 권한을 사용하여 그룹, 사용자 및 연결을 만들기 위한 Microsoft Graph API를 호출합니다. 또한 그룹 식별자를 캐시하여 필터링 속도를 높이기 위해 API를 사용합니다.

  10. 테넌트에 대한 관리자 동의 허용을 선택하여 동의 프로세스를 완료합니다.

사용자 및 그룹 만들기

설정된 애플리케이션에 검색을 추가하는 경우 Azure Active Directory에 기존 사용자 및 그룹 식별자가 있을 수 있습니다. 이 경우 다음 세 단계를 건너뛸 수 있습니다.

그러나 기존 사용자가 없는 경우에는 Microsoft Graph API를 사용하여 보안 주체를 만들 수 있습니다. 다음 코드 조각은 Azure AI 검색 인덱스의 보안 필드에 대한 데이터 값이 되는 식별자를 생성하는 방법을 보여줍니다. 앞에서 예로 든 대학 입학 지원서에서는 입학 담당의 보안 식별자가 됩니다.

사용자 및 그룹 멤버 자격은 유동적이며, 조직 규모가 클수록 더욱 그렇습니다. 조직 멤버 자격의 변경 내용을 선택할 수 있을 만큼 사용자 및 그룹 ID를 빌드하는 코드를 충분히 자주 실행해야 합니다. 마찬가지로, Azure AI 검색 인덱스에는 허용된 사용자 및 리소스의 현재 상태를 반영하도록 비슷한 업데이트 일정이 필요합니다.

1단계 - 그룹 생성

private static Dictionary<Group, List<User>> CreateGroupsWithUsers(string tenant)
{
    Group group = new Group()
    {
        DisplayName = "My First Prog Group",
        SecurityEnabled = true,
        MailEnabled = false,
        MailNickname = "group1"
    };

2단계 - 사용자 생성

User user1 = new User()
{
    GivenName = "First User",
    Surname = "User1",
    MailNickname = "User1",
    DisplayName = "First User",
    UserPrincipalName = String.Format("user1@{0}", tenant),
    PasswordProfile = new PasswordProfile() { Password = "********" },
    AccountEnabled = true
};

3단계: 사용자 및 그룹 연결

List<User> users = new List<User>() { user1, user2 };
Dictionary<Group, List<User>> groups = new Dictionary<Group, List<User>>() { { group, users } };

4단계: 그룹 식별자 캐시

필요에 따라 네트워크 대기 시간을 줄이려면 사용자 그룹 연결을 캐시하여 검색 요청이 실행될 때 그룹이 캐시에서 반환되어 왕복을 저장할 수 있습니다. Batch API를 사용하여 여러 사용자와 단일 Http 요청을 보내고 캐시를 빌드할 수 있습니다.

Microsoft Graph는 많은 양의 요청을 처리하도록 설계되었습니다. 요청이 너무 많이 발생하면 Microsoft Graph가 HTTP 상태 코드 429와 함께 요청을 실패합니다. 자세한 내용은 Microsoft Graph 제한을 참조하세요.

그룹이 허용된 인덱스 문서

Azure AI 검색의 쿼리 작업은 Azure AI 검색 인덱스를 통해 실행됩니다. 이 단계에서 인덱싱 작업은 보안 필터로 사용되는 식별자를 포함하여 검색 가능한 데이터를 인덱스로 가져옵니다.

Azure AI 검색은 사용자 ID를 인증하지 않거나 사용자가 볼 수 있는 권한이 있는 콘텐츠를 설정하기 위한 논리를 제공하지 않습니다. 보안 조정에 대한 사용 사례에서는 중요한 문서와 해당 문서에 대한 액세스 권한을 가진 그룹 식별자를 연결하고 온전한 상태로 검색 인덱스로 가져온 것으로 가정합니다.

가상의 예제에서 Azure AI 검색 인덱스의 PUT 요청 본문에는 지원자의 대학 에세이 또는 성적증명서와 함께 해당 콘텐츠를 볼 권한이 있는 그룹 식별자가 포함됩니다.

이 연습의 코드 샘플에 사용된 일반적인 예에서는 인덱스 작업이 다음과 같이 표시될 수 있습니다.

private static void IndexDocuments(string indexName, List<string> groups)
{
    IndexDocumentsBatch<SecuredFiles> batch = IndexDocumentsBatch.Create(
        IndexDocumentsAction.Upload(
            new SecuredFiles()
            {
                FileId = "1",
                Name = "secured_file_a",
                GroupIds = new[] { groups[0] }
            }),
              ...
            };

IndexDocumentsResult result = searchClient.IndexDocuments(batch);

검색 요청 실행

보안 조정을 위해 인덱스의 보안 필드 값은 검색 결과에 문서를 포함하거나 제외하는 데 사용되는 고정적인 값입니다. 예를 들어, 입학에 대한 그룹 식별자가 “A11B22C33D44-E55F66G77-H88I99JKK”인 경우, 보안 파일에 해당 식별자가 포함된 Azure AI 검색 인덱스의 모든 문서는 호출자에게 다시 전송되는 검색 결과에 포함(또는 제외)됩니다.

요청을 실행하는 사용자 그룹을 기반으로 검색 결과에 반환되는 문서를 필터링하려면 다음 단계를 검토합니다.

1단계: 사용자의 그룹 식별자 검색

사용자 그룹이 아직 캐시되지 않았거나 캐시가 만료된 경우 그룹 요청을 실행합니다.

private static async void RefreshCache(IEnumerable<User> users)
{
    HttpClient client = new HttpClient();
    var userGroups = await _microsoftGraphHelper.GetGroupsForUsers(client, users);
    _groupsCache = new ConcurrentDictionary<string, List<string>>(userGroups);
}

2단계: 검색 요청 작성

사용자의 그룹 멤버 자격을 갖고 있다면 적절한 필터 값이 포함된 검색 요청을 실행할 수 있습니다.

private static void SearchQueryWithFilter(string user)
{
    // Using the filter below, the search result will contain all documents that their GroupIds field   
    // contain any one of the Ids in the groups list
    string filter = String.Format("groupIds/any(p:search.in(p, '{0}'))", string.Join(",", String.Join(",", _groupsCache[user])));
    SearchOptions searchOptions =
        new SearchOptions()
        {
            Filter = filter
        };
    searchOptions.Select.Add("name");

    SearchResults<SecuredFiles> results = searchClient.Search<SecuredFiles>("*", searchOptions);

    Console.WriteLine("Results for groups '{0}' : {1}", _groupsCache[user], results.GetResults().Select(r => r.Document.Name));
}

3단계: 결과 처리

응답에는 사용자가 볼 권한이 있는 문서로 구성된 필터링된 목록이 포함됩니다. 검색 결과 페이지를 작성하는 방법에 따라 필터링된 결과 집합을 반영하는 시각적 신호를 포함할 수 있습니다.

핵심 내용

이 연습에서는 사용자 로그인을 사용하여 Azure AI Search 결과에서 문서를 필터링하고 요청에 제공된 필터와 일치하지 않는 문서의 결과를 잘라내는 패턴을 알아보았습니다.