Skip to main content

Microsoft Entra 租户数据

可以对 Backstage 目录进行设置,以便通过 Microsoft Graph API 直接从 Microsoft Entra ID 中的租户摄取组织数据(用户和团队)。

安装

默认情况下没有安装该软件包,因此必须添加@backstage/plugin-catalog-backend-module-msgraph到您的后端软件包。

# From your Backstage root directory
yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-msgraph

接下来将基本配置添加到app-config.yaml

app-config.yaml
catalog:
providers:
microsoftGraphOrg:
default:
tenantId: ${AZURE_TENANT_ID}
user:
filter: accountEnabled eq true and userType eq 'member'
group:
filter: >
securityEnabled eq false
and mailEnabled eq true
and groupTypes/any(c:c+eq+'Unified')
schedule:
frequency: PT1H
timeout: PT50M

最后,在catalog.ts对于大型组织,该插件可能需要很长时间,因此首次尝试时要注意设置低频率/超时和导入大量用户/组。

packages/backend/src/plugins/catalog.ts
import { MicrosoftGraphOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-msgraph';

export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);

builder.addEntityProvider(
MicrosoftGraphOrgEntityProvider.fromConfig(env.config, {
logger: env.logger,
scheduler: env.scheduler,
}),
);

// ..
}

使用 Microsoft Graph 验证

地方发展

对于本地开发环境,建议您安装 Azure CLI 或 Azure PowerShell,并登录到它们。 或者,您也可以使用带有 Azure 扩展的 VSCode,如果您安装了@azure/identity-vscode设置完成后,插件将通过 Microsoft Graph API 进行身份验证,而无需配置任何凭证或授予任何特殊权限。 如果无法做到这一点,则必须创建应用程序注册。

应用程序注册

如果其他身份验证方法都不起作用,您可以在 azure 门户中创建应用程序注册。 默认情况下,图形插件需要 Microsoft Graph 的以下应用程序权限(非授权):

  • GroupMember.Read.All * User.Read.All

如果贵组织需要管理员同意才能获得这些权限,则需要授予管理员同意。

在使用客户 ID/客户Secret进行身份验证时,您可以设置AZURE_TENANT_ID,AZURE_CLIENT_IDAZURE_CLIENT_SECRET环境变量,或在配置

microsoftGraphOrg:
default:
##...
clientId: 9ef1aac6-b454-4e69-9cf5-7199df049281
clientSecret: REDACTED

要使用证书而不是客户端Secret进行身份验证,可以设置AZURE_TENANT_ID,AZURE_CLIENT_IDAZURE_CLIENT_CERTIFICATE_PATH环境

管理身份

如果部署到支持受管身份的资源并配置了身份(例如 Azure 应用服务、Azure 容器应用),受管身份应该会被选中,而无需任何额外配置。 如果您的应用程序有多个受管身份,您可能需要设置AZURE_CLIENT_ID环境变量,告诉 Azure Identity 使用哪个身份。

向受管身份授予与应用程序注册_以上、请遵循本指南

过滤导入的用户和组

默认情况下,插件会从目录中导入所有用户和组。 可以通过以下方式进行自定义滤波器搜索请注意,如果省略了用户或组属性的筛选器和搜索查询,插件将自动导入所有可用的用户或组。

小组

通过配置搜索查询或筛选器,可以获得更小的组群集。 如果同时配置搜索查询和筛选器,则可以获得更小的组群集。filtersearch的组必须同时符合这两个条件才能被摄取。

microsoftGraphOrg:
providerId:
group:
filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified')
search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'

除了这些组之外,还将为您的组织创建一个额外的组。 所有导入的组都将是该组的子组。

用户

导入用户有两种模式 - 您可以导入所有符合以下条件的用户对象filter.

microsoftGraphOrg:
providerId:
user:
filter: accountEnabled eq true and userType eq 'member'

您也可以导入属于特定组的用户。searchfilter只导入直接组员,不导入临时用户。

microsoftGraphOrg:
providerId:
userGroupMember:
filter: "displayName eq 'Backstage Users'"
search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'

Customizing Transformation

可通过提供自定义转换器对摄入的实体进行定制。 这些转换器可用于完全替换内置逻辑,或通过使用默认转换器 (defaultGroupTransformer,defaultUserTransformerdefaultOrganizationTransformer也可以通过返回以下信息将实体排除在Backstage之外undefined.

这些变压器将在配置时注册。MicrosoftGraphOrgEntityProvider

builder.addEntityProvider(
MicrosoftGraphOrgEntityProvider.fromConfig(env.config, {
// ...
groupTransformer: myGroupTransformer,
userTransformer: myUserTransformer,
organizationTransformer: myOrganizationTransformer,
}),
);

在使用自定义转换器时,您可能希望自定义返回的数据,可提供多个配置选项来调整 Microsoft 图形查询,以获取所需的数据

microsoftGraphOrg:
providerId:
user:
expand: manager
group:
expand: member
select: ['id', 'displayName', 'description']

以下是每种变压器的示例

import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
import {
defaultGroupTransformer,
defaultUserTransformer,
defaultOrganizationTransformer,
} from '@backstage/plugin-catalog-backend-module-msgraph';
import { GroupEntity, UserEntity } from '@backstage/catalog-model';

// This group transformer completely replaces the built in logic with custom logic.
export async function myGroupTransformer(
group: MicrosoftGraph.Group,
groupPhoto?: string,
): Promise<GroupEntity | undefined> {
return {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: group.id!,
annotations: {},
},
spec: {
type: 'Microsoft Entra ID',
children: [],
},
};
}

// This user transformer makes use of the built in logic, but also sets the description field
export async function myUserTransformer(
graphUser: MicrosoftGraph.User,
userPhoto?: string,
): Promise<UserEntity | undefined> {
const backstageUser = await defaultUserTransformer(graphUser, userPhoto);

if (backstageUser) {
backstageUser.metadata.description = 'Loaded from Microsoft Entra ID';
}

return backstageUser;
}

// Example organization transformer that removes the organization group completely
export async function myOrganizationTransformer(
graphOrganization: MicrosoftGraph.Organization,
): Promise<GroupEntity | undefined> {
return undefined;
}

疑难解答

无数据

首先检查日志中的信息Reading msgraph users and groups如果看不到,请检查您是否注册了提供商,以及计划表是否有效。

如果您看到日志条目Read 0 msgraph users and 0 msgraph groups请检查您的搜索和过滤参数。

如果您看到启动信息 (Reading msgraph users and groups),但没有结束信息 (Read X msgraph users and Y msgraph groups),那么很可能是由于数据量过大导致任务耗时过长。 默认行为是导入所有用户和组,这通常会超出所需的数据量。 尝试导入较小的数据集(例如filter: displayName eq 'John Smith').

验证/令牌错误

参见排除 Azure 身份验证问题

从 Microsoft Graph 读取用户时出错:Authorization_RequestDenied - 权限不足,无法完成操作

  • 如果您的组织已将 "管理员同意 "配置为必填项,请确保已为应用程序权限授予此权限 * 如果您的组查询返回的是 Microsoft Teams 组,则可能需要授予额外权限(例如,"Team.ReadBasic.All"、"TeamMember.Read.All") * 如果您已添加额外的 "选择 "或 "展开 "字段,则可能需要授予额外权限