Crea un connettore di identità

Per impostazione predefinita, Google Cloud Search riconosce solo le identità Google in Google Cloud Directory. Utilizza i connettori di identità per sincronizzare le identità aziendali con le identità Google utilizzate da Cloud Search.

Google offre queste opzioni per lo sviluppo di connettori di identità:

Crea un connettore di identità utilizzando l'SDK Identity Connector

Un tipico connettore di identità esegue queste attività:

  1. Configura il connettore.
  2. Recupera gli utenti dal tuo sistema di identità e li invia a Google.
  3. Recupera i gruppi dal tuo sistema di identità e li invia a Google.

Configurare le dipendenze

Includi queste dipendenze nel file di build.

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 la configurazione del connettore

Ogni connettore utilizza un file di configurazione per parametri come l'ID repository. Definisci i parametri come coppie chiave-valore, ad esempio api.sourceId=1234567890abcdef.

Google Cloud Search SDK include parametri forniti da Google per tutti i connettori. Devi dichiarare quanto segue nel file di configurazione:

  • Connettore di contenuti: dichiara api.sourceId e api.serviceAccountPrivateKeyFile. Questi identificano il tuo repository e la chiave privata necessaria per l'accesso.
  • Connettore di identità: dichiara api.identitySourceId per identificare l'origine identità esterna. Per la sincronizzazione degli utenti, dichiara anche api.customerId (l'ID univoco del tuo account Google Workspace).

Dichiara altri parametri forniti da Google solo per eseguire l'override dei valori predefiniti. Per informazioni dettagliate sulla generazione di ID e chiavi, vedi Parametri forniti da Google.

Puoi anche definire parametri specifici per il repository nel file di configurazione.

Trasferisci il file di configurazione al connettore

Imposta la proprietà di sistema config per passare il file di configurazione. Utilizza l'argomento -D quando avvii il connettore. Ad esempio:

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

Se ometti questo argomento, l'SDK tenta di utilizzare un file denominato connector-config.properties nella directory locale.

Crea un connettore di identità di sincronizzazione completa utilizzando una classe modello

L'SDK include un modello FullSyncIdentityConnector per sincronizzare tutti gli utenti e i gruppi dal repository. Questa sezione spiega come utilizzarlo.

Questa sezione fa riferimento al codice dell'esempio IdentityConnectorSample.java, che legge le identità dai file CSV.

Implementa il punto di ingresso del connettore

L'entry point è il metodo main(). Crea un'istanza di Application e chiama start() per eseguire il connettore.

Prima di chiamare application.start(), utilizza IdentityApplication.Builder per creare un'istanza del modello 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();
}

L'SDK chiama initConfig() dopo le chiamate al metodo main() Application.build(). Il metodo initConfig():

  1. Garantisce che Configuration non sia già inizializzato.
  2. Inizializza l'oggetto Configuration con le coppie chiave-valore fornite da Google.

Implementa l'interfaccia Repository

L'oggetto Repository sincronizza le identità del repository con le identità Google. Quando utilizzi un modello, devi solo eseguire l'override di determinati metodi. Per FullSyncIdentityConnector, esegui l'override di questi metodi:

  • init(): Per la configurazione e l'inizializzazione.
  • listUsers(): Per sincronizzare tutti gli utenti.
  • listGroups(): Per sincronizzare tutti i gruppi.
  • (Facoltativo) close(): Per la pulizia durante l'arresto.

Ottenere parametri di configurazione personalizzati

Recupera i parametri personalizzati dall'oggetto Configuration, in genere nel metodo init(). Il seguente snippet mostra come recuperare i percorsi 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();
}

Per ottenere e analizzare un parametro contenente più valori, utilizza uno dei parser di tipo della classe Configuration per analizzare i dati in blocchi discreti. Il seguente snippet, dal connettore del tutorial, utilizza il metodo getMultiValue per ottenere un elenco di nomi di repository GitHub:

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

Recuperare la mappatura per tutti gli utenti

Esegui l'override di listUsers() per recuperare le mappature degli utenti. Questo metodo accetta un checkpoint per riprendere la sincronizzazione in caso di interruzione. Per ogni utente:

  1. Recupera la mappatura tra l'identità Google e l'identità esterna.
  2. Inserisci la coppia nell'iteratore restituito da listUsers().

Ottenere una mappatura degli utenti

Questo snippet mostra il recupero delle mappature delle identità da un file 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);
    }
  }
  // ...
}

Pacchettizzare una mappatura utente in un iteratore

Il metodo listUsers() restituisce un CheckpointCloseableIterable di oggetti IdentityUser.

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

Ottieni un gruppo

Esegui l'override di listGroups() per recuperare i gruppi e i relativi membri. Questo metodo accetta un checkpoint. Per ogni gruppo:

  1. Recupera il gruppo e i relativi membri.
  2. Raggruppali nell'iteratore restituito da listGroups().

Ottieni l'identità del gruppo

Questo snippet mostra il recupero di gruppi e membri da un file 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);
    }
  }
  // ...

}

Raggruppa il gruppo e i membri in un iteratore

Il metodo listGroups() restituisce un CheckpointCloseableIterable di oggetti IdentityGroup.

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

Passaggi successivi