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, los usuarios pueden estar representados por cuentas locales o utilizar el acceso federado con un proveedor de identidad y un ID, distintos de la dirección de correo electrónico del usuario, para identificar cada cuenta. Este ID se denomina el 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 cuando ocurra cualquiera de las dos situaciones que se indican a continuación:

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

Las fuentes de identidad mejoran la eficiencia de la indexación; para ello, se separa la indexación de la asignación de identidad. Esta separación te permite aplazar la búsqueda del usuario cuando crees LCA e indexes elementos.

Implementación de ejemplo

La Figura 1 muestra una implementación de ejemplo en la que una empresa utiliza tanto los repositorios locales como los repositorios en la nube. Cada repositorio utiliza un tipo diferente de ID externo para referirse a los usuarios.

Implementación de ejemplo
Figura 1: Implementación empresarial de ejemplo con tipos de identidades diferentes.

El repositorio 1 identifica al usuario con la dirección de correo electrónico confirmada mediante SAML. Debido a que el repositorio 1 tiene conocimiento de la dirección de correo electrónico principal del usuario en Google Workspace o Cloud Directory, no se necesita una fuente de identidad.

El repositorio 2 se integra directamente en un directorio local y, además, identifica al usuario por su atributo sAMAccountName. Debido a que el repositorio 2 usa un atributo sAMAccountName como ID externo, se necesita una fuente de identidad.

Crear una fuente de identidad

Si necesitas una fuente de identidad, consulta Mapea identidades de usuario en Cloud Search.

Debes crear una fuente de identidad antes de crear un conector de contenido porque necesitarás el ID de la fuente de identidad para crear LCA e indexar datos. Como se mencionó anteriormente, la creación de una fuente de identidad también crea una propiedad del usuario personalizada en Cloud Directory. Utiliza esta propiedad para registrar el ID externo de cada usuario en el repositorio. Se asigna un nombre a esta propiedad con el uso de la convención IDENTITY_SOURCE_ID_identity.

En la siguiente tabla, se muestran dos fuentes de identidad, una para contener los nombres de la cuentas SAM (sAMAccountName) como ID externos y otra para contener los ID de usuarios (uid) como ID externos.

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

Crea una fuente de identidad para cada ID externo posible que se utilice para hacer referencia a un usuario en la empresa.

En la siguiente tabla, se muestra cómo un usuario con una Cuenta de Google y dos ID externos (id1_identity y id2_identity) y sus valores aparecen en Cloud Directory:

usuario correo electrónico id1_identity id2_identity
Ann ann@example.com example\ann 1001

Puedes hacer referencia al mismo usuario mediante tres ID diferentes, (correo electrónico de Google, sAMAccountName y uid) cuando se formulen las LCA para la indexación.

Escribe LCA de usuario

Utiliza el método getUserPrincpal() o el método getGroupPrincipal() para crear principales con el uso de un ID externo proporcionado.

En el siguiente ejemplo, se demuestra cómo obtener permisos de archivos. Estos permisos incluyen el nombre de cada usuario que tiene acceso al archivo.

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

En el siguiente fragmento de código, se muestra cómo crear principales que son propietarios con el uso del ID externo (externalUserName) almacenado en los atributos.

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

Por último, en el siguiente fragmento de código, se muestra cómo crear principales que son lectores del archivo.

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 una lista de lectores y propietarios, puedes crear 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 subyacente usa el patrón identitysources/IDENTITY_SOURCE_ID/users/EXTERNAL_ID para el ID cuando se crean principales. Con referencia a las tablas anteriores, si creas una LCA con id1_identity (SAMAccountName) de Ann, el ID establecería una conexión con el siguiente elemento:

identitysources/id1_identity/users/example/ann

Este ID completo se denomina ID intermedio del usuario porque proporciona un puente entre el ID externo y los ID de Google almacenados en Cloud Directory.

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

Mapea grupos

Las fuentes de identidad también actúan como un espacio de nombres para los grupos que se utilizan en las LCA. Puedes usar esta característica de espacio de nombres para crear y mapear grupos utilizados solo con fines de seguridad o que son locales en un repositorio.

Utiliza la API de Cloud Identity Groups para crear un grupo y administrar las membresías. Para asociar el grupo con una fuente de identidad, utiliza el nombre del recurso de la fuente de identidad como espacio de nombres del grupo.

En el siguiente fragmento de código, se muestra cómo crear un grupo con el uso de la API de Cloud Identity Groups:

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

Para crear una LCA grupal, utiliza el método getGroupPrincipal() a fin de crear un principal grupal con el uso de un ID externo proporcionado. Luego, compila la LCA con la clase Acl.Builder de la siguiente manera:

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

Si bien puedes usar ID externos que no sean de Google para indexar elementos y crear LCA, los usuarios no pueden ver los elementos en una búsqueda hasta que los ID externos establezcan un vínculo con un ID de Google en Cloud Directory. Existen tres maneras de garantizar que Cloud Directory conozca tanto el ID de Google como los ID externos de un usuario:

Los conectores de identidad son programas utilizados para mapear ID externos de identidades empresariales (usuarios y grupos) a identidades internas de Google que Google Cloud Search utiliza. Si tienes que crear una fuente de identidad, debes crear un conector de identidad.

Google Cloud Directory Sync (GCDS) es un ejemplo de un conector de identidad. Este conector de identidad mapea información de usuarios y grupos de Active Directory de Microsoft a Cloud Directory junto con los atributos de usuario que pueden representar su identidad en otros sistemas.

Sincronizar identidades con la API de REST

Utiliza el método update para sincronizar identidades con la API de REST.

Cómo volver a asignar identidades

Después de volver a asignar la identidad de un elemento a otra, debes volver a indexar los elementos para que se aplique la identidad nueva. Por ejemplo:

  • Si intentas quitar una asignación de un usuario o volver a asignarla a otro, la asignación original se conserva hasta que vuelves a indexar.
  • Si borras un grupo asignado que está presente en la LCA de un elemento y, luego, creas un grupo nuevo con el mismo groupKey, el grupo nuevo no proporcionará acceso al elemento hasta que se vuelva a indexar.