同步處理不同識別資訊系統

Google Cloud Search 的存取權控管是以使用者的 Google 帳戶為基礎。將內容編入索引時,項目的所有 ACL 都必須解析為有效的 Google 使用者或群組 ID (電子郵件地址)。

在許多情況下,存放區無法直接瞭解 Google 帳戶。相反地,使用者可以由本機帳戶表示,或使用非使用者電子郵件地址的聯合登入來識別各個帳戶。這組 ID 稱為外部 ID

使用管理控制台建立識別資訊來源,可協助您利用以下方式消除識別資訊系統之間的差距:

如符合下列任一情況,請使用識別資訊來源:

  • 存放區不知道 Google Workspace 或 Google Cloud Directory 中使用者的主要電子郵件地址。
  • 存放區定義的群組不能對應至 Google Workspace 中的電子郵件型群組。

識別資訊來源會將索引與識別資訊對應區隔開來,藉此提升索引效率。這樣分離,您就能在建立 ACL 和索引項目時延後查詢使用者。

部署範例

圖 1 顯示一個企業同時使用內部部署和雲端存放區的部署範例。每個存放區分別使用不同的外部 ID 來指稱使用者。

部署範例
圖 1 使用不同身分類型的企業部署範例。

存放區 1 會使用 SAML 所宣告的電子郵件地址識別使用者。由於存放區 1 知道 Google Workspace 或 Cloud Directory 中使用者的主要電子郵件地址,因此不需要識別資訊來源。

存放區 2 會直接與內部部署目錄整合,並透過 sAMAccountName 屬性識別使用者。由於存放區 2 使用 sAMAccountName 屬性做為外部 ID,因此需要識別資訊來源。

建立識別資訊來源

如果您需要識別資訊來源,請參閱「在 Cloud Search 中對應使用者身分」一文。

建立內容連接器之前,您必須先建立識別資訊來源,因為您需要識別資訊來源 ID,才能建立 ACL 和索引資料。如前所述,建立識別資訊來源也會在 Cloud Directory 中建立一個自訂使用者屬性。使用此屬性記錄存放區中每位使用者的外部 ID。屬性採用慣例 IDENTITY_SOURCE_ID_identity 命名。

下表顯示兩個識別資訊來源,其中一個用於保存 SAM 帳戶名稱 (sAMAccountName) 做為外部 ID,另一個用於保留使用者 ID (uid) 做為外部 ID。

識別資訊來源 使用者屬性 外部 ID
id1 id1_identity sAMAccountName
id2 id2_identity uid

針對用來參照企業內使用者的每個可能外部 ID,建立識別資訊來源。

下表說明擁有 Google 帳戶和兩個外部 ID (id1_identity 和 id2_identity) 的使用者,以及其值在 Cloud Directory 中的顯示方式:

使用者 電子郵件地址 id1_identity id2_identity
小安 ann@example.com 範例\ann 1001

設定要建立索引的 ACL 時,您可以使用三種不同的 ID (Google 電子郵件、sAMAccountName 和 uid) 來參照同一位使用者。

寫入使用者 ACL

請使用 getUserPrincpal() 方法或 getGroupPrincipal() 方法,以提供的外部 ID 建立主體。

以下範例說明如何擷取檔案權限。這些權限包括擁有檔案存取權的所有使用者的名稱。

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)
);

最後,下列程式碼片段說明如何建立屬於檔案讀取者的主體。

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 在建立主體時會使用模式 identitysources/IDENTITY_SOURCE_ID/users/EXTERNAL_ID 做為 ID。回顧上一個表格。如果您使用 Ann 的 id1_identity (SAMAccountName) 建立 ACL,則 ID 會解析為:

identitysources/id1_identity/users/example/ann

整個 ID 稱為使用者的中繼 ID,因為這個 ID 在外部 ID 和透過 Cloud Directory 儲存的 Google ID 之間提供橋接。

如要進一步瞭解如何建立用於存放區的 ACL 模型,請參閱 ACL

對應群組

識別資訊來源也可以做為 ACL 中使用的群組的命名空間。您可以使用此命名空間功能,建立及對應群組,僅用於安全性用途或位於存放區的本機。

使用 Cloud Identity Groups API 建立群組並管理成員資格。如要將群組與識別資訊來源建立關聯,請使用識別資訊來源資源名稱做為群組命名空間。

下列程式碼片段說明如何使用 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);
}

識別資訊連接器

雖然您可以使用外部的非 Google ID 建立 ACL 和索引項目,但使用者的外部 ID 會解析為 Cloud Directory 中的 Google ID,使用者才能在搜尋結果中看到項目。有三種方式可確保 Cloud Directory 同時知道使用者的 Google ID 和外部 ID:

識別資訊連接器是一種程式,用於將企業身分 (使用者和群組) 的外部 ID 對應至 Google Cloud Search 使用的內部 Google 身分。如果您需要建立識別資訊來源,則必須建立識別資訊連接器。

Google Cloud Directory Sync (GCDS) 就屬於識別資訊連接器。這個識別資訊連接器會將使用者和群組資訊,從 Microsoft 的 Active Directory 對應至 Cloud Directory,以及可能代表在其他系統中身分的使用者屬性。

使用 REST API 同步處理身分

使用 update 方法,透過 REST API 同步處理身分。

重新對應身分

將某個項目的身分重新對應至其他身分後,您必須重新為項目重新建立索引,新身分才會保留。舉例來說,

  • 如果您嘗試移除使用者的對應關係,或將對應關係重新對應至其他使用者,系統仍會保留原始對應關係,直到重新建立索引為止。
  • 如果您刪除項目 ACL 中的對應群組,然後以相同的 groupKey 建立新群組,則新群組並不會提供項目的存取權,直到項目重新建立索引為止。