יצירת מחבר זהות

כברירת מחדל, Google Cloud Search מזהה רק זהויות Google שמאוחסנות ב-Google Cloud Directory (משתמשים וקבוצות). מחברים של זהויות משמשים לסנכרון זהויות הארגון לזהויות Google שבהן נעשה שימוש ב-Google Cloud Search.

Google מספקת את האפשרויות הבאות לפיתוח מחברי זהות:

  • ה-SDK של Identity Connector. האפשרות הזו מיועדת למפתחים שמתכננים בשפת התכנות Java. ה-SDK של Identity Connector הוא wrapper מסביב ל-API ל-REST, שמאפשר לכם ליצור מחברים במהירות. במאמר יצירת מחבר זהות באמצעות Identity Connector SDK מוסבר איך יוצרים מחבר זהויות באמצעות ה-SDK.

  • API ל-REST וספריות API ברמה נמוכה. האפשרויות האלה מתאימות למפתחים שיכול להיות שהם לא מתכנתים ב-Java או שבסיס הקוד שלהם מתאים יותר ל-API ל-REST או לספרייה. כדי ליצור מחבר זהויות באמצעות API ל-REST, ראו Directory API: חשבונות משתמשים למידע על מיפוי משתמשים, ובמסמכי התיעוד של Cloud Identity למידע על מיפוי קבוצות.

יצירת מחבר זהויות באמצעות Identity Connector SDK

מחבר זהויות טיפוסי מבצע את המשימות הבאות:

  1. הגדר את המחבר.
  2. מאחזרים את כל המשתמשים ממערכת הזהויות של הארגון ושולחים אותם ל-Google לסנכרון עם הזהויות של Google.
  3. אחזור כל הקבוצות ממערכת הזהויות של הארגון ושליחה שלהן ל-Google לצורך סנכרון עם הזהויות של Google.

הגדרה של יחסי תלות

כדי להשתמש ב-SDK, צריך לכלול יחסי תלות מסוימים בקובץ ה-build. לוחצים על הכרטיסייה שלמטה כדי להציג את יחסי התלות של סביבת ה-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'

יצירת ההגדרות האישיות של המחבר

לכל מחבר יש קובץ תצורה המכיל פרמטרים שהמחבר משתמש בהם, כמו המזהה של המאגר. פרמטרים מוגדרים צמדי key-value, כמו api.sourceId=1234567890abcdef.

ה-SDK של Google Cloud Search מכיל מספר פרמטרים של תצורה שסופקו על ידי Google, ומשמשים את כל המחברים. בקובץ התצורה עליכם להצהיר על הפרמטרים הבאים שסופקו על ידי Google:

  • עבור מחבר תוכן, עליכם להצהיר על api.sourceId ועל api.serviceAccountPrivateKeyFile מכיוון שהפרמטרים האלה מזהים את מיקום המאגר והמפתח הפרטי שנדרשים כדי לגשת למאגר.
  • עבור מחבר זהויות, עליך להצהיר על api.identitySourceId מכיוון שהפרמטר הזה מזהה את המיקום של מקור הזהות החיצוני שלך. אם אתם מסנכרנים את המשתמשים, עליכם גם להצהיר על api.customerId בתור המזהה הייחודי של חשבון Google Workspace של הארגון.

אין צורך להצהיר עליהם בקובץ התצורה, אלא אם אתם רוצים לשנות את ערכי ברירת המחדל של פרמטרים אחרים שסופקו על ידי Google. למידע נוסף על הפרמטרים של ההגדרות שסופקו על ידי Google, כמו יצירה של מזהים ומפתחות מסוימים, קראו את המאמר פרמטרים של תצורה ש-Google מספקת.

תוכלו גם להגדיר פרמטרים ספציפיים למאגר לשימוש בקובץ התצורה.

העברת קובץ התצורה למחבר

מגדירים את מאפיין המערכת config כדי להעביר את קובץ התצורה למחבר. אפשר להגדיר את המאפיין באמצעות הארגומנט -D כשמפעילים את המחבר. לדוגמה, הפקודה הבאה מפעילה את המחבר עם קובץ התצורה MyConfig.properties:

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

אם הארגומנט הזה חסר, ה-SDK ינסה לגשת לקובץ תצורה בשם connector-config.properties המוגדר כברירת מחדל.

יצירת מחבר מלא של זהות סנכרון באמצעות מחלקת תבנית

ה-SDK של Identity Connector מכיל מחלקת תבנית FullSyncIdentityConnector, שניתן להשתמש בה כדי לסנכרן את כל המשתמשים והקבוצות ממאגר הזהויות עם זהויות Google. בקטע הזה מוסבר איך משתמשים בתבנית FullSyncIdentityConnector כדי לבצע סנכרון מלא של משתמשים וקבוצות ממאגר זהויות שאינו של Google.

הקטע הזה במסמכים מתייחס לקטעי קוד מהדוגמה IdentityConnecorSample.java. בדוגמה הזו קוראים את זהויות המשתמשים והקבוצות משני קובצי CSV, ומסנכרנת אותן עם זהויות Google.

הטמעת נקודת הכניסה של המחבר

נקודת הכניסה למחבר היא השיטה main(). המשימה הראשית בשיטה הזו היא ליצור מכונה של המחלקה Application ולהפעיל את השיטה start() כדי להפעיל את המחבר.

לפני שמפעילים את application.start(), צריך להשתמש במחלקה IdentityApplication.Builder כדי ליצור את התבנית FullSyncIdentityConnector. FullSyncIdentityConnector מקבל אובייקט Repository שאת השיטות שלו תטמיעו. קטע הקוד הבא מראה כיצד ליישם את השיטה 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();
}

מאחורי הקלעים, ה-SDK קורא לשיטה initConfig() אחרי שהפונקציה main() של המחבר קוראת ל-Application.build. השיטה initConfig() מבצעת את המשימות הבאות:

  1. הפונקציה מפעילה את השיטה Configuation.isInitialized() כדי לוודא שה-Configuration לא אותחל.
  2. הפעלת אובייקט Configuration באמצעות זוגות המפתח/ערך ש-Google מספקת. כל צמד מפתח/ערך מאוחסן באובייקט ConfigValue בתוך האובייקט Configuration.

הטמעת הממשק Repository

המטרה היחידה של האובייקט Repository היא לבצע סנכרון של זהויות המאגר לזהויות Google. כשמשתמשים בתבנית, צריך לשנות רק שיטות מסוימות בממשק Repository כדי ליצור מחבר זהויות. בשירות FullTraversalConnector, סביר להניח שתבטלו את השיטות הבאות:

  • השיטה init(). כדי להגדיר מאגר זהויות ולהפעיל אותו, משנים את השיטה 'init() '.

  • השיטה listUsers(). כדי לסנכרן את כל המשתמשים במאגר הזהויות עם משתמשי Google, משנים את השיטה listUsers().

  • השיטה listGroups(). על מנת לסנכרן את כל הקבוצות במאגר הזהויות עם קבוצות Google, צריך לבטל את השיטה listGroups().

  • (אופציונלי) השיטה close(). אם אתם צריכים לבצע ניקוי מאגר, עדיף לשנות את השיטה close(). השיטה הזו מופעלת פעם אחת במהלך כיבוי המחבר.

אחזור של פרמטרים מותאמים אישית של הגדרות אישיות

כחלק מהטיפול בתצורת המחבר, עליך לקבל פרמטרים מותאמים אישית מהאובייקט Configuration. המשימה הזו בדרך כלל מתבצעת בשיטה init() של המחלקה Repository.

למחלקה Configuration יש מספר שיטות לקבלת סוגים שונים של נתונים מתצורה. כל שיטה מחזירה אובייקט ConfigValue. לאחר מכן משתמשים ב-method get() של האובייקט ConfigValue כדי לאחזר את הערך בפועל. קטע הקוד הבא מראה איך לאחזר את הערכים userMappingCsvPath ו-groupMappingCsvPath מאובייקט 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();
}

כדי לקבל ולנתח פרמטר שמכיל כמה ערכים, אפשר להשתמש באחד מהכלי לניתוח סוג של מחלקה Configuration כדי לנתח את הנתונים למקטעים נפרדים. קטע הקוד הבא, מהמחבר של המדריך, משתמש ב-method getMultiValue כדי לקבל רשימה של שמות המאגרים ב-GitHub:

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

קבל את המיפוי עבור כל המשתמשים

שינוי של listUsers() כדי לאחזר את המיפוי של כל המשתמשים ממאגר הזהויות. השיטה listUsers() מקבלת נקודת ביקורת שמייצגת את הזהות האחרונה לסנכרון. אפשר להשתמש בנקודת הביקורת כדי להמשיך את הסנכרון במקרה שהתהליך יופסק. עבור כל משתמש במאגר, מבצעים את השלבים הבאים בשיטה listUsers():

  1. קבלת מיפוי שמורכב מהזהות של Google ומהזהות החיצונית שמשויכת אליה.
  2. אורזים את הצמד באיטרטור שמוחזר באמצעות השיטה listUsers().

אחזור של מיפוי משתמשים

קטע הקוד הבא מדגים איך לאחזר את מיפויי הזהויות שמאוחסנים בקובץ 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);
    }
  }
  // ...
}

חבילה של מיפוי משתמש באיטרטור

השיטה listUsers() מחזירה Iterator, באופן ספציפי CheckpointCloseableIterable, של אובייקטים IdentityUser. אפשר להשתמש במחלקה CheckpointClosableIterableImpl.Builder כדי ליצור ולהחזיר איטרטור. קטע הקוד הבא מראה כיצד לארוז כל מיפוי לתוך איטרטור ה-build של הרשימה מהרשימה הזו:

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

אחזור של קבוצה

שינוי listGroups() כדי לאחזר את כל הקבוצות והחברים בהן ממאגר הזהויות שלך. השיטה listGroups() מקבלת נקודת ביקורת שמייצגת את הזהות האחרונה שסונכרנה. אפשר להשתמש בנקודת הביקורת כדי להמשיך את הסנכרון אם התהליך יופסק. עבור כל משתמש במאגר, מבצעים את השלבים הבאים בשיטה listGroups():

  1. מורידים את הקבוצה ואת החברים בה.
  2. אורזים כל קבוצה וחברים באיטרטור שמוחזר באמצעות השיטה listGroups().

קבלת זהות הקבוצה

קטע הקוד הבא מדגים איך לאחזר את הקבוצות והחברים ששמורים בקובץ 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);
    }
  }
  // ...

}

סוגרים את הקבוצה והחברים באיטרטור

השיטה listGroups() מחזירה Iterator, באופן ספציפי CheckpointCloseableIterable, של אובייקטים IdentityGroup. אפשר להשתמש במחלקה CheckpointClosableIterableImpl.Builder כדי ליצור ולהחזיר איטרטור. קטע הקוד הבא מראה איך לארוז כל קבוצה וחברים ברשימה וליצור את האיטרטור מהרשימה הזו:

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

השלבים הבאים

פירטנו כאן כמה פעולות שאפשר לבצע:

  • (אופציונלי) מטמיעים את השיטה close() כדי לשחרר משאבים לפני הסגירה.
  • (אופציונלי) צור מחבר תוכן באמצעות ה-SDK של מחבר התוכן.