서로 다른 ID 시스템 동기화

Google Cloud Search에서는 사용자의 Google 계정을 기준으로 액세스를 제어합니다. 콘텐츠의 색인을 생성할 때 항목의 모든 ACL은 유효한 Google 사용자 또는 그룹 ID(이메일 주소)를 확인해야 합니다.

대부분의 경우 저장소에는 Google 계정에 대한 직접적인 정보가 없습니다. 대신 로컬 계정으로 사용자를 나타내거나, 사용자의 이메일 주소가 아닌 ID와 ID 공급업체 제휴 로그인을 사용하여 각 계정을 식별할 수 있습니다. 이 ID를 외부 ID라고 합니다.

관리 콘솔을 사용하여 만든 ID 소스를 사용하면 다음과 같은 방법으로 ID 시스템 간의 이러한 간격을 해소할 수 있습니다.

다음 중 한 가지에 해당하면 ID 소스를 사용합니다.

  • 저장소가 Google Workspace 또는 Google Cloud 디렉터리에 있는 사용자의 기본 이메일 주소를 알지 못합니다.
  • 저장소가 Google Workspace의 이메일 기반 그룹에 해당하지 않는 액세스 제어 그룹을 정의합니다.

ID 소스를 사용하면 색인 생성이 ID 매핑에서 분리되므로 색인 생성 효율성이 향상됩니다. 이러한 분리를 통해 ACL을 만들고 항목 색인을 생성할 때 사용자 조회를 연기할 수 있습니다.

배포 예

그림 1은 기업에서 온프레미스 저장소와 클라우드 저장소를 모두 사용하는 배포 예를 보여줍니다. 각 저장소는 서로 다른 유형의 외부 ID를 사용하여 사용자를 참조합니다.

배포 예시
그림 1. 서로 다른 ID 유형을 사용하는 기업 배포의 예

저장소 1은 SAML로 보장되는 이메일 주소를 사용하여 사용자를 식별합니다. 저장소 1은 Google Workspace 또는 Cloud Directory에 있는 사용자의 기본 이메일 주소를 알고 있으므로 ID 소스가 필요하지 않습니다.

저장소 2는 온프레미스 디렉터리와 직접 통합되며 sAMAccountName 속성으로 사용자를 식별합니다. 저장소 2에서는 sAMAccountName 속성을 외부 ID로 사용하므로 ID 소스가 필요합니다.

ID 소스 만들기

ID 소스가 필요한 경우, Cloud Search에서 사용자 ID 매핑을 참조하세요.

ACL 및 색인 데이터를 만들려면 ID 소스 ID가 필요하므로 콘텐츠 커넥터를 만들기 전에 ID 소스를 만들어야 합니다. 앞에서의 설명처럼 ID 소스를 만들면 커스텀 사용자 속성도 Google Cloud 디렉터리에 생성됩니다. 이 속성을 사용하여 저장소에 있는 각 사용자의 외부 ID를 기록할 수 있습니다. 이 속성은 IDENTITY_SOURCE_ID_identity 규칙에 따라 이름이 지정됩니다.

다음 표에서는 ID 소스 두 개를 보여줍니다. 하나는 SAM 계정 이름(sAMAccountName)을 외부 ID로 보관하고, 다른 하나는 사용자 ID(uid)를 외부 ID로 보관합니다.

ID 소스 사용자 속성 외부 ID
id1 id1_identity sAMAccountName
id2 id2_identity uid

기업 사용자를 참조하는 데 사용할 수 있는 각 외부 ID의 ID 소스를 만듭니다.

다음 표에서는 Google 계정과 외부 ID 두 개(id1_identity 및 id2_identity)를 가진 사용자와 관련 값이 Cloud Directory에 어떻게 나타나는지 보여줍니다.

사용자 이메일 id1_identity id2_identity
Ann ann@example.com example\ann 1001

색인을 생성하려고 ACL을 작성할 때 서로 다른 세 가지 ID(Google 이메일, sAMAccountName, uid)를 사용하여 동일한 사용자를 참조할 수 있습니다.

사용자 ACL 작성

제공된 외부 ID를 사용하여 주 구성원을 만들려면 getUserPrincpal() 메서드 또는 getGroupPrincipal() 메서드를 사용합니다.

다음 예에서는 파일 권한 검색 방법을 보여줍니다. 이러한 권한에는 파일 액세스 권한이 있는 사용자 각각의 이름이 포함됩니다.

FilePermissionSample.java
/**
 * Sample for mapping permissions from a source repository to Cloud Search
 * ACLs. In this example, POSIX file permissions are used a the source
 * permissions.
 *
 * @return Acl
 * @throws IOException if unable to read file permissions
 */
static Acl mapPosixFilePermissionToCloudSearchAcl(Path pathToFile) throws IOException {
  // Id of the identity source for external user/group IDs. Shown here,
  // but may be omitted in the SDK as it is automatically applied
  // based on the `api.identitySourceId` configuration parameter.
  String identitySourceId = "abcdef12345";

  // Retrieve the file system permissions for the item being indexed.
  PosixFileAttributeView attributeView = Files.getFileAttributeView(
      pathToFile,
      PosixFileAttributeView.class,
      LinkOption.NOFOLLOW_LINKS);

  if (attributeView == null) {
    // Can't read, return empty ACl
    return new Acl.Builder().build();
  }

  PosixFileAttributes attrs = attributeView.readAttributes();
  // ...
}

다음 코드 스니펫은 속성에 저장된 외부 ID (externalUserName)를 사용하여 소유자인 주 구성원을 만드는 방법을 보여줍니다.

FilePermissionSample.java
// Owner, for search quality.
// Note that for principals the name is not the primary
// email address in Cloud Directory, but the local ID defined
// by the OS. Users and groups must be referred to by their
// external ID and mapped via an identity source.
List<Principal> owners = Collections.singletonList(
    Acl.getUserPrincipal(attrs.owner().getName(), identitySourceId)
);

마지막으로 다음 코드 스니펫은 파일 리더(reader)인 주 구성원을 만드는 방법을 보여줍니다.

FilePermissionSample.java
// List of users to grant access to
List<Principal> readers = new ArrayList<>();

// Add owner, group, others to readers list if permissions
// exist. For this example, other is mapped to everyone
// in the organization.
Set<PosixFilePermission> permissions = attrs.permissions();
if (permissions.contains(PosixFilePermission.OWNER_READ)) {
  readers.add(Acl.getUserPrincipal(attrs.owner().getName(), identitySourceId));
}
if (permissions.contains(PosixFilePermission.GROUP_READ)) {
  String externalGroupName = attrs.group().getName();
  Principal group = Acl.getGroupPrincipal(externalGroupName, identitySourceId);
  readers.add(group);
}
if (permissions.contains(PosixFilePermission.OTHERS_READ)) {
  Principal everyone = Acl.getCustomerPrincipal();
  readers.add(everyone);
}

리더와 소유자 목록이 있으면 ACL을 만들 수 있습니다.

FilePermissionSample.java
// Build the Cloud Search ACL. Note that inheritance of permissions
// from parents is omitted. See `setInheritFrom()` and `setInheritanceType()`
// methods on the builder if required by your implementation.
Acl acl = new Acl.Builder()
    .setReaders(readers)
    .setOwners(owners)
    .build();

기본 REST API는 주 구성원을 만들 때 ID에 identitysources/IDENTITY_SOURCE_ID/users/EXTERNAL_ID 패턴을 사용합니다. 이전 표로 돌아가서 Ann의 id1_identity (SAMAccountName)로 ACL을 만들면 ID가 다음과 같이 확인됩니다.

identitysources/id1_identity/users/example/ann

이 전체 ID를 사용자의 중간 ID라 합니다. 외부 ID와 Google Cloud 디렉터리에 저장된 Google ID 사이에 연결 다리를 제공하기 때문입니다.

저장소에 사용할 ACL 모델링에 대한 자세한 내용은 ACL을 참조하세요.

그룹 매핑

또한 ID 소스는 ACL에 사용되는 그룹의 네임스페이스 역할도 합니다. 이 네임스페이스 기능을 사용하여 보안 용도로만 사용되거나 저장소에 로컬인 그룹을 만들고 매핑할 수 있습니다.

Cloud Identity Groups API를 사용하여 그룹을 만들고 멤버십을 관리할 수 있습니다. 그룹을 ID 소스와 연결하려면 ID 소스 리소스 이름을 그룹 네임스페이스로 사용합니다.

다음 코드 스니펫은 Cloud Identity Groups API를 사용하여 그룹을 만드는 방법을 보여줍니다.

CreateGroupCommand.java
String namespace = "identitysources/" + idSource;
Group group = new Group()
    .setGroupKey(new EntityKey().setNamespace(namespace).setId(groupId))
    .setDescription("Demo group")
    .setDisplayName(groupName)
    .setLabels(Collections.singletonMap("system/groups/external", ""))
    .setParent(namespace);
try {
  CloudIdentity service = Utils.buildCloudIdentityService();
  Operation createOperation = service.groups().create(group).execute();

  if (createOperation.getDone()) {
    // Note: The response contains the data for a Group object, but as
    // individual fields. To convert to a Group instance, either populate
    // the fields individually or serialize & deserialize to/from JSON.
    //
    // Example:
    // String json = service.getJsonFactory().toString(response);
    // Group createdGroup =  service.getObjectParser()
    //     .parseAndClose(new StringReader(json), Group.class);
    System.out.printf("Group: %s\n",
        createOperation.getResponse().toString());
  } else {
    // Handle case where operation not yet complete, poll for
    // completion. API is currently synchronous and all operations return
    // as completed.
    // ...
  }
} catch (Exception e) {
  System.err.printf("Unable to create group: %s", e.getMessage());
  e.printStackTrace(System.err);
}

그룹 ACL 만들기

그룹 ACL을 만들려면 getGroupPrincipal() 메서드와 제공된 외부 ID를 사용하여 그룹 주 구성원을 만듭니다. 그런 다음 다음과 같이 Acl.Builder 클래스를 사용하여 ACL을 빌드합니다.

FilePermissionSample.java
if (permissions.contains(PosixFilePermission.GROUP_READ)) {
  String externalGroupName = attrs.group().getName();
  Principal group = Acl.getGroupPrincipal(externalGroupName, identitySourceId);
  readers.add(group);
}

ID 커넥터

Google ID가 아닌 외부 ID를 사용하여 ACL을 만들고 항목 색인을 생성할 수 있지만 사용자는 외부 ID가 Google Cloud 디렉터리에 있는 Google ID로 확인될 때까지 검색 항목을 확인할 수 없습니다. 다음 3가지 방법으로 Google Cloud 디렉터리가 사용자의 Google ID와 외부 ID를 모두 알고 있는지 여부를 확인할 수 있습니다.

  • 관리 콘솔을 통해 각 개별 사용자 프로필을 수동으로 업데이트합니다. 이 프로세스는 사용자 프로필 여러 개로 테스트하고 프로토타입을 제작하는 경우에만 권장됩니다.
  • Directory API를 사용하여 외부 ID를 Google ID에 매핑합니다. 이 프로세스는 ID 커넥터 SDK를 사용할 수 없는 경우에 권장됩니다.
  • ID 커넥터 SDK를 사용하여 ID 커넥터를 만듭니다. 이 SDK를 사용하면 Directory API를 사용하여 ID를 간편하게 매핑할 수 있습니다.

ID 커넥터는 기업 ID(사용자 및 그룹)의 외부 ID를 Google Cloud Search에서 사용하는 내부 Google ID에 매핑하는 프로그램입니다. ID 소스를 만들어야 하는 경우에는 ID 커넥터를 만들어야 합니다.

Google 클라우드 디렉토리 동기화(GCDS)는 ID 커넥터의 한 가지 예입니다. 이 ID 커넥터는 다른 시스템에서 ID를 나타낼 수 있는 사용자 속성과 함께 Microsoft Active Directory의 사용자 및 그룹 정보를 Google Cloud 디렉터리에 매핑합니다.

REST API로 ID 동기화

update 메서드를 사용하여 REST API를 통해 ID를 동기화합니다.

ID 재매핑

항목의 ID를 다른 ID로 재매핑한 후 새 ID가 적용되도록 항목의 색인을 다시 생성해야 합니다. 예를 들면 다음과 같습니다.

  • 사용자에서 매핑을 삭제하거나 다른 사용자에게 재매핑하려고 하면 색인을 다시 만들 때까지 원래 매핑이 계속 유지됩니다.
  • 항목 ACL에 있는 매핑된 그룹을 삭제한 다음 동일한 groupKey로 새 그룹을 만들면 항목의 색인이 다시 생성될 때까지 새 그룹에서 항목에 액세스할 수 없습니다.