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

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

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

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

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

יצירת מחבר זהויות באמצעות ה-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'

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

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

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

נקודת הכניסה למחבר היא ה-method main(). המשימה העיקרית של השיטה הזו היא ליצור מכונה של המחלקה Application ולהפעיל את ה-method 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 קורא ל-method initConfig() אחרי הפעלת ה-method main() של המחבר Application.build. השיטה initConfig() מבצעת את המשימות הבאות:

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

הטמעת הממשק של Repository

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

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

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

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

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

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

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

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

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

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

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

קבוצה

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

  1. מקבלים את הקבוצה ואת החברים בה.
  2. אורזים כל קבוצה וחברים באיטרטור שמוחזר באמצעות ה-method 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);
    }
  }
  // ...

}

לארוז את הקבוצה ואת החברים באיטרטור

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

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

השלבים הבאים

אפשר לנסות את הפתרונות הבאים:

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