マイクロアプリ

ユーザープロバイダーの構成

ユーザープロバイダーを構成すると、レコードシステム(SoR)のIDプロバイダーの構成設定で作成および管理されるユーザーグループを複製および同期する必要がなくなるため、管理効率を向上できます。

マイクロアプリ管理者は、SoRからユーザーおよびユーザーグループのデータを収集し、このデータを使用してすべての統合でマイクロアプリのサブスクリプションを管理するようにユーザープロバイダーを構成できます。ユーザープロバイダーを構成するには、アプリケーションのSoRでユーザー/ユーザーグループを公開するAPIが提供されている必要があります(ServiceNow、Salesforce、Jiraなど)。

ユーザープロバイダーの作成

新しいユーザープロバイダーを手動で作成するか、既に構成されているユーザープロバイダーをインポートできます。

次の手順を実行します:

  1. [マイクロアプリ統合] ページで、上部のバーにある [ユーザープロバイダー] タブを選択します。

    [ユーザープロバイダー]タブ

  2. ユーザープロバイダーの種類を選択します。[HTTP Webサービスから新しいユーザープロバイダーを作成する] を選択して、このユーザープロバイダーを手動で構成します。[以前に構成したユーザープロバイダーをインポートする] こともできます。インポートについて詳しくは、「インポート」を参照してください。
  3. 接続の [ユーザープロバイダー名] を入力します。
  4. ユーザープロバイダーの [ベース URL] を入力します。
  5. アイコンライブラリからユーザープロバイダーのアイコンを選択するか、デフォルトのアイコンのままにしておきます。
  6. [サービス認証] 方法を選択し、使用する認証方法に基づいて必要なすべての詳細を入力します。認証方法について詳しくは、「サービス認証のセットアップ」を参照してください。
  7. (オプション)必要に応じて [要求レート制限の有効化] トグルを有効にし、[要求数][時間間隔] を入力します。
  8. (オプション)必要に応じて [要求のタイムアウト] の値を入力します。
  9. [追加] を選択して、ユーザープロバイダーの作成を終了します。

    ユーザープロバイダーの構成画面

    次に、スクリプトをインポートして終了します。

スクリプトのインポート

マイクロアプリのユーザープロバイダースクリプト機能を使用して、ユーザープロバイダーのセットアップを完了するためのスクリプトをアップロードする必要があります。スクリプトの要件とJavaScriptモデルを以下に示します。「スクリプトの準備」を参照してください。スクリプトに関する一般的な情報については、「HTTP統合スクリプティング」を参照してください。

(前述の手順で)ユーザープロバイダーを追加すると、ページが開き、ユーザープロバイダーのビューが表示されます。次の手順に従って、スクリプトを追加します。

  1. [ステータス] 下にある [スクリプトの追加] を選択します。
  2. [スクリプトのインポート] を選択します。
  3. スクリプトをインポートポップアップにドラッグするか、ファイルを参照します。スクリプトは、1MB以下の.jsファイルである必要があります。

    スクリプトが解析され、検証されます。

  4. [インポート] を選択して終了します。

    スクリプトの詳細は、 ユーザープロバイダーの [ユーザープロバイダースクリプト] ビューにある [スクリプトハンドラー ] の下に表示されます。スクリプトによって作成された要求を表示するには、ユーザープロバイダーエントリの横にあるメニューを選択し、[ログの同期]を選択します。

サブスクライバーを割り当てるときに、新しいユーザープロバイダーを使用できるようになりました。詳しくは、「利用者の管理」を参照してください。

サブスクリプションのユーザープロバイダー

スクリプトの準備

スクリプトを準備するときは、次の要件を考慮してください:

  • インポートスクリプトは、組み込みライブラリmicroapp-user-groupsを読み込むことにより開始する必要があります。このライブラリは、データベースに保存する必要があるオブジェクトを定義します:const { User, Group, UserGroupMapping } = library.load("microapp-user-groups");
  • オブジェクトには次の構造またはプロパティがあります:

    • User(accountName, displayName, email, domain, userPrincipalName, userId) メールアドレスはユーザープロバイダー内で一意である必要があります
    • Group(accountName, displayName, domain, userPrincipalName, groupId, parentGroupId) グループ階層もparentGroupIdを使用して定義されます
    • UserGroupMapping(userId, groupId) ユーザーをグループにマッピングします
  • すべてのプロパティはデータ型がSTRINGです。
  • User.emailは、Citrix Workspaceにログインしているユーザーのメールと一致する必要があります。

モデルスクリプト

以下のJavaScriptコードをモデルとして使用します。

次のモデルは、ServiceNow SoR専用に作成されています。このスクリプトは他のサービスと互換性がありません。

    const { User, Group, UserGroupMapping } = library.load("microapp-user-groups");

    function fullSync(params) {
      fullSyncUsers(params);
      fullSyncGroups(params);
      fullSyncUserGroupMapping(params);
    }

    function fullSyncUsers({ client, dataStore }) {
      let offset = 0;
      do {
        const response = client.fetchSync(
          `/api/now/table/sys_user?sysparm_fields=sys_domain_path%2Cname%2C%20sys_id%2Cuser_name%2Cemail&sysparm_query=emailISNOTEMPTY^active%3Dtrue&sysparm_limit=100&sysparm_offset=${offset}`
        );
        if (!response.ok) {
          console.log("Error status:", response.status, response.statusText);
          console.log("Error body:", response.textSync());
          throw new Error("Network response was not ok");
        }
        console.log("fetch done");

        const users = response.jsonSync().result;
        console.log("users");

        users.map((user) =>
          console.log(
            user.user_name,
            user.name,
            user.email,
            user.sys_domain_path,
            user.name,
            user.sys_id
          )
        );
        dataStore.save(
          User.tableModel,
          users.map(
            (user) =>
              new User(
                user.user_name,
                user.name,
                user.email,
                user.sys_domain_path,
                user.user_name,
                user.sys_id
              )
          )
        );

        offset = offset + 100;
        console.log(`offset: ${offset}`);
      } while (offset < 300);
    }

    function fullSyncGroups({ client, dataStore }) {
      let offset = 0;
      do {
        const response = client.fetchSync(
          `/api/now/table/sys_user_group?sysparm_query=active%3Dtrue&sysparm_limit=100&sysparm_offset=${offset}`
        );
        if (!response.ok) {
          console.log("Error status:", response.status, response.statusText);
          console.log("Error body:", response.textSync());
          throw new Error("Network response was not ok");
        }

        const groups = response.jsonSync().result;
        groups.map((group) =>
          console.log(
            group.name,
            group.name,
            "/",
            group.name,
            group.sys_id,
            group.parent.value
          )
        );
        dataStore.save(
          Group.tableModel,
          groups.map(
            (group) =>
              new Group(
                group.name,
                group.name,
                "/",
                group.name,
                group.sys_id,
                group.parent.value
              )
          )
        );
        offset = offset + 100;
        console.log(`offset: ${offset}`);
      } while (offset < 400);
    }

    function fullSyncUserGroupMapping({ client, dataStore }) {
      let offset = 0;
      do {
        const response = client.fetchSync(
          `/api/now/table/sys_user_grmember?&sysparm_limit=100&sysparm_offset=${offset}`
        );
        if (!response.ok) {
          console.log("Error status:", response.status, response.statusText);
          console.log("Error body:", response.textSync());
          throw new Error("Network response was not ok");
        }

        const mappings = response.jsonSync().result;
        mappings.map((mapping) =>
          console.log(mapping.user.value, mapping.group.value)
        );
        dataStore.save(
          UserGroupMapping.tableModel,
          mappings.map(
            (mapping) =>
              new UserGroupMapping(mapping.user.value, mapping.group.value)
          )
        );
        offset = offset + 100;
        console.log(`offset: ${offset}`);
      } while (offset < 400);
    }

    integration.define({
      synchronizations: [
        {
          name: "snowUserGroups", // Logical name
          fullSyncFunction: fullSync,
        },
      ],
      model: {
        tables: [User.tableModel, Group.tableModel, UserGroupMapping.tableModel],
      },
    });
<!--NeedCopy-->
ユーザープロバイダーの構成