Sincronizar sistemas de identidad diferentes

El control de acceso en Google Cloud Search se basa en la Cuenta de Google del usuario. Cuando se indexa el contenido, todas las LCA de los elementos deben establecer un vínculo con los ID de usuarios o grupos de Google válidos (direcciones de correo electrónico).

En muchos casos, un repositorio no tiene conocimiento directo de las Cuentas de Google. En su lugar, las cuentas locales representan a los usuarios, o bien los usuarios utilizan el acceso federado con un proveedor de identidad. Esta identificación, además de la dirección de correo electrónico, se denomina ID externo.

Las fuentes de identidad, que se crean con la Consola del administrador, ayudan a salvar la distancia entre los sistemas de identidad de la siguiente manera:

Utiliza fuentes de identidad en los siguientes casos:

  • El repositorio no conoce la dirección de correo electrónico principal del usuario en Google Workspace o Google Cloud Directory.
  • El repositorio define grupos de control de acceso que no corresponden a los grupos basados en correos electrónicos en Google Workspace.

Las fuentes de identidad mejoran la eficiencia al separar la indexación de la asignación de identidad. Esto te permite aplazar la búsqueda del usuario cuando crees LCA y elementos de indexación.

Implementación de ejemplo

En la Figura 1, se muestra una empresa que usa repositorios locales y en la nube. Cada uno usa un tipo diferente de ID externo.

Ejemplo de implementación empresarial con diferentes tipos de identidades
Figura 1: Ejemplo de implementación empresarial con diferentes tipos de identidades.

El repositorio 1 identifica a los usuarios por dirección de correo electrónico con SAML. Como conoce la dirección de correo electrónico principal en Google Workspace o Cloud Directory, no necesita una fuente de identidad.

El repositorio 2 se integra en un directorio local y, además, identifica a los usuarios por medio de sAMAccountName. Debido a que usa este atributo como ID externo, requiere una fuente de identidad.

Crear una fuente de identidad

Si necesitas una fuente de identidad, consulta Asigna identidades de usuarios en Cloud Search.

Crea la fuente de identidad antes de crear un conector de contenido. Necesitarás su ID para crear LCA y datos de índice. La creación de una fuente de identidad también crea una propiedad del usuario personalizada en Cloud Directory para almacenar IDs externos. El nombre de la propiedad usa la convención IDENTITY_SOURCE_ID_identity.

En esta tabla, se muestran dos fuentes de identidad: una para los nombres de las cuentas SAM y otra para los IDs de usuarios (uid).

Fuente de identidad Propiedad del usuario ID externo
id1 id1_identity sAMAccountName
id2 id2_identity uid

Crea una fuente de identidad para cada tipo de ID externo que se use en tu empresa.

En esta tabla, se muestra cómo aparece un usuario con una Cuenta de Google y dos IDs externos en Cloud Directory:

Usuario Correo electrónico id1_identity id2_identity
Ann ann@example.com example\ann 1001

Puedes hacer referencia al mismo usuario con cualquiera de estos IDs cuando se formulen las LCA para la indexación.

Escribir LCA de usuario

Usa getUserPrincipal() o getGroupPrincipal() para crear principales con IDs externos.

En este ejemplo, se recuperan los permisos de archivos, incluidos los usuarios con acceso:

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();
  // ...
}

Este fragmento crea principales para los propietarios con el atributo 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)
);

Este fragmento crea principales para los lectores:

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

Una vez que tengas lectores y propietarios, crea la LCA:

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

La API de REST usa el patrón identitysources/IDENTITY_SOURCE_ID/users/EXTERNAL_ID. El id1_identity de Ana se resuelve como identitysources/id1_identity/users/example/ann. Este es el ID intermedio del usuario.

Para obtener más información sobre el modelado de las LCA del repositorio, consulta LCA.

Asignar grupos

Las fuentes de identidad también actúan como un espacio de nombres para los grupos de LCA. Úsala para crear y asignar grupos que se usen solo con fines de seguridad o que sean locales en un repositorio.

Utiliza la API de Cloud Identity Groups para crear grupos y administrar membresías. Asocia el grupo con una fuente de identidad usando el nombre de la fuente de identidad como espacio de nombres.

Este fragmento crea un grupo:

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

Crear una LCA grupal

Usa getGroupPrincipal() para crear un principal de grupo con un ID externo y, luego, compila la LCA:

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

Conectores de identidad

Los usuarios no pueden ver los elementos en los resultados de la búsqueda hasta que los IDs externos establezcan un vínculo con un ID de Google en Cloud Directory. Puedes asegurarte de que esto suceda de tres maneras:

Los conectores de identidad asignan IDs externos de identidades empresariales a identidades internas de Google. Si creas una fuente de identidad, también debes crear un conector de identidad.

Google Cloud Directory Sync (GCDS) es un ejemplo de un conector de identidad. Asigna información de usuarios y grupos de Active Directory a Cloud Directory.

Sincronizar identidades con la API de REST

Usa el método update para sincronizar identidades.

Reasigna identidades

Después de reasignar una identidad, debes volver a indexar los elementos para que el cambio se aplique.

  • Si quitas o cambias una asignación de usuario, la asignación original permanece hasta que se vuelva a indexar.
  • Si borras un grupo asignado y creas uno nuevo con el mismo groupKey, no se otorgará acceso hasta que vuelvas a indexar.