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

Google Cloud Search 的存取權控管是以使用者的 Google 帳戶為依據。建立索引時,項目上的所有 ACL 都必須解析為有效的 Google 使用者或群組 ID (電子郵件地址)。

在許多情況下,存放區並未直接瞭解 Google 帳戶。相反地,使用者可能會以本機帳戶表示,或利用使用者電子郵件地址以外的識別資訊提供者和 ID 聯合登入來識別各個帳戶。這組 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 中的顯示方式:

使用者 email 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 會使用 ID 模式 identitysources/IDENTITY_SOURCE_ID/users/EXTERNAL_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 的新群組,那麼除非將項目重新編入索引,否則新群組不會提供該項目的存取權。