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
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
对于大型组织,该插件可能需要很长时间,因此首次尝试时要注意设置低频率/超时和导入大量用户/组。
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_ID
和AZURE_CLIENT_SECRET
环境变量,或在配置
microsoftGraphOrg:
default:
##...
clientId: 9ef1aac6-b454-4e69-9cf5-7199df049281
clientSecret: REDACTED
要使用证书而不是客户端Secret进行身份验证,可以设置AZURE_TENANT_ID
,AZURE_CLIENT_ID
和AZURE_CLIENT_CERTIFICATE_PATH
环境
管理身份
如果部署到支持受管身份的资源并配置了身份(例如 Azure 应用服务、Azure 容器应用),受管身份应该会被选中,而无需任何额外配置。 如果您 的应用程序有多个受管身份,您可能需要设置AZURE_CLIENT_ID
环境变量,告诉 Azure Identity 使用哪个身份。
向受管身份授予与应用程序注册_以上、请遵循本指南
过滤导入的用户和组
默认情况下,插件会从目录中导入所有用户和组。 可以通过以下方式进行自定义滤波器和搜索请注意,如果省略了用户或组属性的筛选器和搜索查询,插件将自动导入所有可用的用户或组。
小组
通过配置搜索查询或筛选器,可以获得更小的组群集。 如果同时配置搜索查询和筛选器,则可以获得更小的组群集。filter
和search
的组必须同时符合这两个条件才能被摄取。
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'
您也可以导入属于特定组的用户。search
和filter
只导入直接组员,不导入临时用户。
microsoftGraphOrg:
providerId:
userGroupMember:
filter: "displayName eq 'Backstage Users'"
search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
Customizing Transformation
可通过提供自定义转换器对摄入的实体进行定制。 这些转换器可用于完全替换内置逻辑,或通过使用默认转换器 (defaultGroupTransformer
,defaultUserTransformer
和defaultOrganizationTransformer
也可以通过返回以下信息将实体排除在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'
).