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

Google Cloud Search 的存取權控管功能會根據使用者的 Google 帳戶運作。建立內容索引時,項目的所有 ACL 都必須解析為有效的 Google 使用者或群組 ID (電子郵件地址)。

在許多情況下,存放區不會直接知道 Google 帳戶。相反地,使用者可以透過本機帳戶代表,或使用聯合登入功能,搭配身分識別提供者和 ID (而非使用者電子郵件地址) 來識別每個帳戶。這個 ID 稱為外部 ID

識別資訊來源是透過管理控制台建立,可協助彌補識別系統之間的差距,具體做法如下:

請在下列情況下使用身分識別資訊來源:

  • 存放區無法得知使用者在 Google Workspace 或 Google Cloud Directory 中的主要電子郵件地址。
  • 這個存放區會定義存取權控制群組,但不對應至 Google Workspace 中的電子郵件群組。

識別資訊來源會將索引與識別資訊對應分開,以提高索引效率。透過這種解耦合方式,您可以在建立 ACL 和索引項目時,暫緩查詢使用者。

部署範例

圖 1 顯示企業同時使用內部部署和雲端存放區的部署範例。每個存放區都會使用不同類型的外部 ID 來參照使用者。

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

Repository 1 會使用透過 SAML 驗證的電子郵件地址,識別使用者。由於存放區 1 已知使用者在 Google Workspace 或 Cloud Directory 中的主電子郵件地址,因此不需要身分識別來源。

Repository 2 會直接整合內部目錄,並根據使用者的 sAMAccountName 屬性進行識別。由於 Repository 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 example\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 和使用 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:

  • 透過管理控制台手動更新每個使用者個人資料。如果您只想使用少數幾個使用者個人資料進行測試和建立原型,建議採用這種做法。
  • 使用 Directory API 將外部 ID 對應至 Google ID。我們建議使用這個程序,適用對象為無法使用 Identity Connector SDK 的使用者。
  • 使用 Identity Connector SDK 建立身分連接器。這個 SDK 可簡化Directory API 的使用方式,以便對應 ID。

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

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

使用 REST API 同步身分

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

重新對應身分

將項目的 ID 重新對應至其他 ID 後,您必須重新為項目建立索引,才能讓新 ID 生效。例如:

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