微应用

配置用户提供商

配置用户提供程序无需复制和同步在记录系统 (SoR) 的身份提供程序配置设置中创建和维护的用户组,从而提高了管理效率。

微应用管理员可以将用户提供商配置为从 SoR 收集用户和用户组数据,并使用这些数据管理所有集成中的微应用订阅。要配置用户提供程序,您的应用程序 SoR 必须提供公开用户/用户组的 API,例如 ServiceNow、Salesforce、Jira 等。

创建用户提供商

您可以手动创建新的用户提供程序,也可以导入已配置的用户提供程序。

请按照以下步骤进行操作:

  1. 微应用集成 页面中,选择顶部栏中的 “ 用户提供商 ” 选项卡。

    用户提供商标签

  2. 选择用户提供商类型。选择 从 HTTP Web 服务创建新的用户提供程序 以手动配置此用户提供程序。您还可以 导入以前配置的用户提供程序。有关导入的详细信息,请参阅 入。
  3. 输入连接的 用户提供程序名称
  4. 输入用户提供商 基本 URL
  5. 图标 库中为用户提供者选择一个图标,或将其保留为默认图标。
  6. 选择 服务身份验证 方法,然后根据您使用的身份验证方法填写所有必需的详细信息。有关身份验证方法的详细信息,请参阅 设置服务身份验证
  7. (可选)根据需要 启用请求速率限制 开关,然后输入 请求数时间间隔
  8. (可选)如果需要,请输入 请求超时 的值。
  9. 选择 添加 以完成用户提供程序的创建。

    用户提供商配置屏幕

    现在你导入一个脚本来完成。

导入脚本

使用微应用中的用 户提供程序脚本 功能,您需要上传脚本才能完成用户提供程序设置。我们在下面提供了脚本要求和 JavaScript 模型。请参阅 准备脚本。有关脚本的一般信息,请参阅 HTTP 集成脚本

添加用户提供程序后(在前面的过程中),页面将打开,其中包含用户提供程序的视图。请按照以下步骤添加脚本。

  1. 选择 状态 下的 添加脚本
  2. 选择 导入脚本
  3. 将脚本拖到导入弹出窗口中,或浏览查找文件。脚本必须是不大于 1 MB 的 .js 文件。

    脚本经过解析和验证。

  4. 选择 导入 完成。

    您可以在用户提供程序的 用户提供程序脚本视图中的脚本 处理程序下看到脚本详细信息。要查看脚本发出的请求,请选择用户提供程序条目旁边的菜单,然后选择 同步日志

现在,在分配订阅者时,您的新用户提供商可用。有关详细信息,请参阅 管理订阅者

订阅中的用户提供商

准备你的脚本

准备脚本时,请考虑以下要求:

  • 导入脚本必须从加载内置库微应用程序用户组开始。此库定义了必须存储在数据库中的对象: 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
  • 用户 .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-->
配置用户提供商