Crea un connettore di identità

Per impostazione predefinita, Google Cloud Search riconosce solo le identità Google archiviate in Google Cloud Directory (utenti e gruppi). I connettori di identità vengono utilizzati per sincronizzare le identità della tua azienda con le identità Google utilizzate da Google Cloud Search.

Google offre le seguenti opzioni per lo sviluppo di connettori di identità:

  • L'SDK del connettore di identità. Questa opzione è destinata agli sviluppatori che programmano nel linguaggio di programmazione Java. L'SDK Identity Connector è un wrapper intorno all'API REST che ti consente di creare rapidamente connettori. Per creare un connettore di identità utilizzando l'SDK, consulta Creare un connettore di identità utilizzando l'SDK Identity Connector.

  • Un'API REST di basso livello e librerie API. Queste opzioni sono destinate agli sviluppatori che potrebbero non programmare in Java o il cui codebase si adatta meglio a un'API REST o a una libreria. Per creare un connettore di identità utilizzando l'API REST, consulta API Directory: User Accounts per informazioni sulla mappatura degli utenti e Documentazione di Cloud Identity per informazioni sulla mappatura dei gruppi.

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

Un tipico connettore di identità esegue le seguenti attività:

  1. Configura il connettore.
  2. Recupera tutti gli utenti dal sistema di identità aziendale e inviali a Google per la sincronizzazione con le identità Google.
  3. Recupera tutti i gruppi dal sistema di identità aziendale e inviali a Google per la sincronizzazione con le identità Google.

Configurare le dipendenze

Per utilizzare l'SDK, devi includere determinate dipendenze nel file di build. Fai clic su una scheda di seguito per visualizzare le dipendenze per l'ambiente 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 ha un file di configurazione contenente i parametri utilizzati dal connettore, ad esempio l'ID del repository. I parametri sono definiti come coppie chiave-valore, ad esempio api.sourceId=1234567890abcdef.

L'SDK Google Cloud Search contiene diversi parametri di configurazione forniti da Google utilizzati da tutti i connettori. Devi dichiarare i seguenti parametri forniti da Google nel file di configurazione:

  • Per un connettore di contenuti, devi dichiarare api.sourceId e api.serviceAccountPrivateKeyFile, in quanto questi parametri identificano la posizione del repository e della chiave privata necessaria per accedervi.
  • Per un connettore di identità, devi dichiarare api.identitySourceId perché questo parametro identifica la posizione dell'origine identità esterna. Se stai sincronizzando gli utenti, devi anche dichiarare api.customerId come ID univoco per l'account Google Workspace della tua azienda.

A meno che tu non voglia sostituire i valori predefiniti di altri parametri forniti da Google, non devi dichiararli nel file di configurazione. Per ulteriori informazioni sui parametri di configurazione forniti da Google, ad esempio su come generare determinati ID e chiavi, consulta Parametri di configurazione forniti da Google.

Puoi anche definire parametri specifici del repository da utilizzare nel file di configurazione.

Trasferisci il file di configurazione al connettore

Imposta la proprietà di sistema config per passare il file di configurazione al connettore. Puoi impostare la proprietà utilizzando l'argomento -D quando avvii il connettore. Ad esempio, il seguente comando avvia il connettore con il file di configurazione MyConfig.properties:

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

Se questo argomento non è presente, l'SDK tenta di accedere a un file di configurazione predefinito denominato connector-config.properties.

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

L'SDK Identity Connector contiene una classe modello FullSyncIdentityConnector che puoi utilizzare per sincronizzare tutti gli utenti e i gruppi dal repository di identità con le identità Google. Questa sezione spiega come utilizzare il modello FullSyncIdentityConnector per eseguire una sincronizzazione completa di utenti e gruppi da un repository di identità non Google.

Questa sezione della documentazione fa riferimento agli snippet di codice dell'esempio IdentityConnecorSample.java. Questo esempio legge le identità di utenti e gruppi da due file CSV e le sincronizza con le identità Google.

Implementa il punto di ingresso del connettore

L'entry point di un connettore è il metodo main(). Il compito principale di questo metodo è creare un'istanza della classe Application e richiamare il relativo metodo start() per eseguire il connettore.

Prima di chiamare application.start(), utilizza la classe IdentityApplication.Builder per creare un'istanza del modello FullSyncIdentityConnector. FullSyncIdentityConnector accetta un oggetto Repository i cui metodi implementerai. Il seguente snippet di codice mostra come implementare il metodo main():

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

Dietro le quinte, l'SDK chiama il metodo initConfig() dopo che il metodo main() del connettore chiama Application.build. Il metodo initConfig() esegue le seguenti attività:

  1. Chiama il metodo Configuation.isInitialized() per assicurarsi che Configuration non sia stato inizializzato.
  2. Inizializza un oggetto Configuration con le coppie chiave-valore fornite da Google. Ogni coppia chiave-valore è archiviata in un oggetto ConfigValue all'interno dell'oggetto Configuration.

Implementa l'interfaccia Repository

L'unico scopo dell'oggetto Repository è eseguire la sincronizzazione delle identità del repository con le identità Google. Quando utilizzi un modello, devi sostituire solo determinati metodi all'interno dell'interfaccia Repository per creare un connettore di identità. Per FullTraversalConnector , probabilmente sostituirai i seguenti metodi:

  • Il metodo init(). Per eseguire la configurazione e l'inizializzazione di qualsiasi repository di identità, esegui l'override del metodo `init()`.

  • Il metodo listUsers(). Per sincronizzare tutti gli utenti nel repository delle identità con gli utenti Google, esegui l'override del metodo listUsers().

  • Il metodo listGroups(). Per sincronizzare tutti i gruppi nel repository delle identità con Google Gruppi, esegui l'override del metodo listGroups().

  • (facoltativo) Il metodo close(). Se devi eseguire la pulizia del repository, esegui l'override del metodo close(). Questo metodo viene chiamato una volta durante l'arresto del connettore.

Ottenere parametri di configurazione personalizzati

Nell'ambito della gestione della configurazione del connettore, dovrai recuperare tutti i parametri personalizzati dall'oggetto Configuration. Questa attività viene solitamente eseguita nel metodo Repository della init() classe.

La classe Configuration ha diversi metodi per ottenere diversi tipi di dati da una configurazione. Ogni metodo restituisce un oggetto ConfigValue. Quindi, utilizza il metodo get() dell'oggetto ConfigValue per recuperare il valore effettivo. Il seguente snippet mostra come recuperare i valori userMappingCsvPath e groupMappingCsvPath da un oggetto Configuration:

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 degli analizzatori 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 listUsers() per recuperare la mappatura per tutti gli utenti dal repository delle identità. Il metodo listUsers() accetta un checkpoint che rappresenta l'ultima identità da sincronizzare. Il checkpoint può essere utilizzato per riprendere la sincronizzazione in caso di interruzione del processo. Per ogni utente nel repository, esegui questi passaggi nel metodo listUsers():

  1. Ottieni una mappatura costituita dall'identità Google e dall'identità esterna associata.
  2. Inserisci la coppia in un iteratore restituito dal metodo listUsers().

Ottieni una mappatura utente

Il seguente snippet di codice mostra come recuperare le mappature delle identità memorizzate in 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 Iterator, in particolare un CheckpointCloseableIterable, di oggetti IdentityUser. Puoi utilizzare la classe CheckpointClosableIterableImpl.Builder per costruire e restituire un iteratore. Il seguente snippet di codice mostra come raggruppare ogni mappatura in un elenco per creare l'iteratore da questo elenco:

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

Ottenere un gruppo

Override listGroups() per recuperare tutti i gruppi e i relativi membri dal repository di identità. Il metodo listGroups() accetta un checkpoint che rappresenta l'ultima identità da sincronizzare. Il checkpoint può essere utilizzato per riprendere la sincronizzazione in caso di interruzione del processo. Per ogni utente nel repository, esegui questi passaggi nel metodo listGroups():

  1. Recupera il gruppo e i relativi membri.
  2. Raggruppa ogni gruppo e i relativi membri in un iteratore restituito dal metodo listGroups().

Ottieni l'identità del gruppo

Il seguente snippet di codice mostra come recuperare i gruppi e i membri memorizzati in 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 Iterator, in particolare un CheckpointCloseableIterable, di oggetti IdentityGroup. Puoi utilizzare la classe CheckpointClosableIterableImpl.Builder per costruire e restituire un iteratore. Il seguente snippet di codice mostra come raggruppare ogni gruppo e i relativi membri in un elenco e creare l'iteratore da questo elenco:

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

Passaggi successivi

Ecco alcuni passaggi successivi che puoi intraprendere: