Crea un conector de identidad

De forma predeterminada, Google Cloud Search solo reconoce las identidades de Google en Google Cloud Directory. Usa conectores de identidad para sincronizar las identidades empresariales con las identidades de Google que usa Cloud Search.

Google brinda las siguientes opciones para desarrollar conectores de identidad:

Crea un conector de identidad con el SDK de conector de identidad

Un conector de identidad típico realiza las siguientes tareas:

  1. Configura el conector.
  2. Recupera los usuarios de tu sistema de identidad y los envía a Google.
  3. Recupera los grupos de tu sistema de identidad y los envía a Google.

Configura dependencias

Incluye estas dependencias en tu archivo de compilación.

Maven

<dependency>
  <groupId>com.google.enterprise.cloudsearch</groupId>
  <artifactId>google-cloudsearch-identity-connector-sdk</artifactId>
  <version>v1-0.0.3</version>
</dependency>

Gradle

compile group: 'com.google.enterprise.cloudsearch',
        name: 'google-cloudsearch-identity-connector-sdk',
        version: 'v1-0.0.3'

Crea tu configuración del conector

Cada conector usa un archivo de configuración para parámetros como el ID de tu repositorio. Define los parámetros como pares clave-valor, como api.sourceId=1234567890abcdef.

El SDK de Google Cloud Search incluye parámetros proporcionados por Google para todos los conectores. Debes declarar lo siguiente en tu archivo de configuración:

  • Conector de contenido: Declara api.sourceId y api.serviceAccountPrivateKeyFile. Estos identifican tu repositorio y la clave privada necesaria para acceder a él.
  • Conector de identidad: Declara api.identitySourceId para identificar tu fuente de identidad externa. Para la sincronización de usuarios, también debes declarar api.customerId (el ID único de tu cuenta de Google Workspace).

Declara otros parámetros proporcionados por Google solo para anular sus valores predeterminados. Para obtener detalles sobre cómo generar IDs y claves, consulta Parámetros proporcionados por Google.

También puedes definir parámetros específicos del repositorio en tu archivo de configuración.

Pasa el archivo de configuración al conector

Establece la propiedad del sistema config para pasar el archivo de configuración. Usa el argumento -D cuando inicies el conector. Por ejemplo:

java -classpath myconnector.jar -Dconfig=MyConfig.properties MyConnector

Si omites este argumento, el SDK intentará usar un archivo llamado connector-config.properties en el directorio local.

Crea un conector de identidad de sincronización completa con una clase de plantilla

El SDK incluye una plantilla FullSyncIdentityConnector para sincronizar todos los usuarios y grupos de tu repositorio. En esta sección, se explica cómo usarla.

En esta sección, se hace referencia al código de la muestra IdentityConnectorSample.java, que lee identidades de archivos CSV.

Implementa el punto de entrada del conector

El punto de entrada es el método main(). Crea una instancia de Application y llama a start() para ejecutar el conector.

Antes de llamar a application.start(), usa IdentityApplication.Builder para crear una instancia de la plantilla FullSyncIdentityConnector.

IdentityConnectorSample.java
/**
 * This sample connector uses the Cloud Search SDK template class for a full
 * sync connector. In the full sync case, the repository is responsible
 * for providing a snapshot of the complete identity mappings and
 * group rosters. This is then reconciled against the current set
 * of mappings and groups in Cloud Directory.
 *
 * @param args program command line arguments
 * @throws InterruptedException thrown if an abort is issued during initialization
 */
public static void main(String[] args) throws InterruptedException {
  Repository repository = new CsvRepository();
  IdentityConnector connector = new FullSyncIdentityConnector(repository);
  IdentityApplication application = new IdentityApplication.Builder(connector, args).build();
  application.start();
}

El SDK llama a initConfig() después de que tu método main() llama a Application.build(). El método initConfig():

  1. Garantiza que Configuration aún no se haya inicializado.
  2. Inicializa el objeto Configuration con los pares clave-valor proporcionados por Google.

Implementa la interfaz Repository

El objeto Repository sincroniza las identidades del repositorio con las identidades de Google. Cuando usas una plantilla, solo necesitas anular ciertos métodos. En el caso de FullSyncIdentityConnector, anula estos métodos:

  • init(): Para la configuración y la inicialización.
  • listUsers(): Para sincronizar todos los usuarios.
  • listGroups(): Para sincronizar todos los grupos
  • (Opcional) close(): Para la limpieza durante el cierre.

Obtén parámetros de configuración personalizados

Recupera parámetros personalizados del objeto Configuration, por lo general, en el método init(). En el siguiente fragmento, se muestra cómo recuperar rutas de CSV:

IdentityConnectorSample.java
/**
 * Initializes the repository once the SDK is initialized.
 *
 * @param context Injected context, contains convenienve methods
 *                for building users & groups
 * @throws IOException if unable to initialize.
 */
@Override
public void init(RepositoryContext context) throws IOException {
  log.info("Initializing repository");
  this.context = context;
  userMappingCsvPath = Configuration.getString(
      "sample.usersFile", "users.csv").get().trim();
  groupMappingCsvPath = Configuration.getString(
      "sample.groupsFile", "groups.csv").get().trim();
}

Para obtener y analizar un parámetro que contenga varios valores, usa uno de los analizadores de tipos de la clase Configuration para analizar los datos en fragmentos separados. En el siguiente fragmento del conector del instructivo, se usa el método getMultiValue para obtener una lista de nombres de repositorios de GitHub:

GithubRepository.java
ConfigValue<List<String>> repos = Configuration.getMultiValue(
    "github.repos",
    Collections.emptyList(),
    Configuration.STRING_PARSER);

Obtén la asignación para todos los usuarios

Anula listUsers() para recuperar las asignaciones de usuarios. Este método acepta un punto de control para reanudar la sincronización si se interrumpe. Para cada usuario, haz lo siguiente:

  1. Obtén la asignación entre la identidad de Google y la identidad externa.
  2. Empaqueta el par en el iterador que muestra listUsers().

Obtén una asignación de usuario

En este fragmento, se muestra cómo recuperar asignaciones de identidad de un archivo CSV:

IdentityConnectorSample.java
/**
 * Retrieves all user identity mappings for the identity source. For the
 * full sync connector, the repository must provide a complete snapshot
 * of the mappings. This is reconciled against the current mappings
 * in Cloud Directory. All identity mappings returned here are
 * set in Cloud Directory. Any previously mapped users that are omitted
 * are unmapped.
 *
 * The connector does not create new users. All users are assumed to
 * exist in Cloud Directory.
 *
 * @param checkpoint Saved state if paging over large result sets. Not used
 *                   for this sample.
 * @return Iterator of user identity mappings
 * @throws IOException if unable to read user identity mappings
 */
@Override
public CheckpointCloseableIterable<IdentityUser> listUsers(byte[] checkpoint)
    throws IOException {
  List<IdentityUser> users = new ArrayList<>();
  try (Reader in = new FileReader(userMappingCsvPath)) {
    // Read user mappings from CSV file
    CSVParser parser = CSVFormat.RFC4180
        .withIgnoreSurroundingSpaces()
        .withIgnoreEmptyLines()
        .withCommentMarker('#')
        .parse(in);
    for (CSVRecord record : parser.getRecords()) {
      // Each record is in form: "primary_email", "external_id"
      String primaryEmailAddress = record.get(0);
      String externalId = record.get(1);
      if (primaryEmailAddress.isEmpty() || externalId.isEmpty()) {
        // Skip any malformed mappings
        continue;
      }
      log.info(() -> String.format("Adding user %s/%s",
          primaryEmailAddress, externalId));

      // Add the identity mapping
      IdentityUser user = context.buildIdentityUser(
          primaryEmailAddress, externalId);
      users.add(user);
    }
  }
  // ...
}

Empaqueta una asignación de usuario en un iterador

El método listUsers() devuelve un CheckpointCloseableIterable de objetos IdentityUser.

IdentityConnectorSample.java
CheckpointCloseableIterable<IdentityUser> iterator =
  new CheckpointCloseableIterableImpl.Builder<IdentityUser>(users)
      .setHasMore(false)
      .setCheckpoint((byte[])null)
      .build();

Obtén un grupo

Anula listGroups() para recuperar grupos y sus miembros. Este método acepta un punto de control. Para cada grupo, haz lo siguiente:

  1. Obtén el grupo y sus miembros.
  2. Empaquétalos en el iterador que muestra listGroups().

Obtén la identidad del grupo

En este fragmento, se muestra cómo recuperar grupos y miembros de un archivo CSV:

IdentityConnectorSample.java
/**
 * Retrieves all group rosters for the identity source. For the
 * full sync connector, the repository must provide a complete snapshot
 * of the rosters. This is reconciled against the current rosters
 * in Cloud Directory. All groups and members  returned here are
 * set in Cloud Directory. Any previously created groups or members
 * that are omitted are removed.
 *
 * @param checkpoint Saved state if paging over large result sets. Not used
 *                   for this sample.
 * @return Iterator of group rosters
 * @throws IOException if unable to read groups
 */    @Override
public CheckpointCloseableIterable<IdentityGroup> listGroups(byte[] checkpoint)
    throws IOException {
  List<IdentityGroup> groups = new ArrayList<>();
  try (Reader in = new FileReader(groupMappingCsvPath)) {
    // Read group rosters from CSV
    CSVParser parser = CSVFormat.RFC4180
        .withIgnoreSurroundingSpaces()
        .withIgnoreEmptyLines()
        .withCommentMarker('#')
        .parse(in);
    for (CSVRecord record : parser.getRecords()) {
      // Each record is in form: "group_id", "member"[, ..., "memberN"]
      String groupName = record.get(0);
      log.info(() -> String.format("Adding group %s", groupName));
      // Parse the remaining columns as group memberships
      Supplier<Set<Membership>> members = new MembershipsSupplier(record);
      IdentityGroup group = context.buildIdentityGroup(groupName, members);
      groups.add(group);
    }
  }
  // ...

}

Empaqueta el grupo y sus miembros en un iterador

El método listGroups() devuelve un CheckpointCloseableIterable de objetos IdentityGroup.

IdentityConnectorSample.java
CheckpointCloseableIterable<IdentityGroup> iterator =
   new CheckpointCloseableIterableImpl.Builder<IdentityGroup>(groups)
      .setHasMore(false)
      .setCheckpoint((byte[])null)
      .build();

Próximos pasos