Skip to main content

LDAP 组织数据

可以对 Backstage 目录进行设置,以便直接从与 LDAP 兼容的服务中摄取组织数据(用户和组)。 这样就形成了一个分层结构,其中包括用户类实体,以反映您的组织设置。

支持的供应商

Backstage 一般支持与 OpenLDAP 兼容的供应商,以及 Active Directory 和 FreeIPA。 如果您使用的供应商似乎不受支持,请提出问题.

安装

本指南将使用实体提供程序方法。 如果你出于某种原因更喜欢处理器方法(不推荐),下文将单独介绍。

默认情况下并未安装该提供程序,因此您必须在@backstage/plugin-catalog-backend-module-ldap到您的后端软件包。

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

注意:当配置使用 Provider 而不是 Processor 时,不 > 需要添加指向 LDAP 服务器的 location

更新后端中的目录插件初始化,添加提供程序并进行调度:

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

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

// The target parameter below needs to match the ldap.providers.target
// value specified in your app-config.
builder.addEntityProvider(
LdapOrgEntityProvider.fromConfig(env.config, {
id: 'our-ldap-master',
target: 'ldaps://ds.example.net',
logger: env.logger,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 60 },
timeout: { minutes: 15 },
}),
}),
);

// ..
}

在此之后,您还必须在应用程序配置中添加一些配置,说明您要为该目标导入的内容。

配置

下面的配置是一个从公司 LDAP 服务器导入组和用户的设置示例。

ldap:
providers:
- target: ldaps://ds.example.net
bind:
dn: uid=ldap-reader-user,ou=people,ou=example,dc=example,dc=net
secret: ${LDAP_SECRET}
users:
dn: ou=people,ou=example,dc=example,dc=net
options:
filter: (uid=*)
map:
description: l
set:
metadata.customField: 'hello'
groups:
dn: ou=access,ou=groups,ou=example,dc=example,dc=net
options:
filter: (&(objectClass=some-group-class)(!(groupType=email)))
map:
description: l
set:
metadata.customField: 'hello'

可能有许多提供商,每个提供商都针对特定的target应该与target即,您将为每个目标添加一个实体提供程序类实例,以便从这些实例中摄取内容。

这些配置块中有很多选项,因此我们将分别介绍配置块中的每个 "根 "键。

目标

这是目标服务器的 URL,一般格式为ldaps://ds.example.net对于启用 SSL 的服务器或ldap://ds.example.net没有 SSL。

绑定

绑定块指定插件应如何与服务器绑定(本质上是验证)。 它包含以下字段。

dn: uid=ldap-reader-user,ou=people,ou=example,dc=example,dc=net
secret: ${LDAP_SECRET}

dn是插件进行身份验证的用户的完整 LDAP 区分名称。 目前只支持基于普通用户的身份验证。

secret是同一用户的密码。 在本例中,它以环境变量的形式给出LDAP_SECRET,必须在后端启动时设置。

用户

users块定义了治理用户读取和解释的设置。 其字段将在下面的章节中分别说明。

users.dn

存储用户的 DN,例如ou=people,ou=example,dc=example,dc=net.

users.options

读取所有用户信息时,向服务器发送查询时使用的搜索选项。 所有选项的默认值如下所示,但它们都是可选的。

options:
# One of 'base', 'one', or 'sub'.
scope: one
# The filter is the one that you commonly will want to specify explicitly. It
# is a string on the standard LDAP query format. Use it to select out the set
# of users that are of actual interest to ingest. For example, you may want
# to filter out disabled users.
filter: (uid=*)
# The attribute selectors for each item, as passed to the LDAP server.
attributes: ['*', '+']
# This field is either 'false' to disable paging when reading from the
# server, or an object on the form '{ pageSize: 100, pagePause: true }' that
# specifies the details of how the paging shall work.
paged: false

users.set

这个可选项可让您指定一些 JSON 路径(a.b.c 格式)以及要在这些路径上设置的硬编码值。 例如,如果您想在生成的实体上硬编码命名空间或类似内容,这将非常有用。

set:
# Just an example; the key and value can be anything
metadata.namespace: 'ldap'

users.map

从众所周知的实体字段到 LDAP 属性名称的映射。 在这里,您可以定义如何解释每个 LDAP 结果项的属性,并将它们移动到相应的实体字段中。 下文显示了所有选项及其默认值,但它们都是可选的。

如果您省略了可选映射,则仍会使用默认值进行复制。displayName在配置中,提供程序仍会复制属性cn输入实体字段spec.profile.displayName.

map:
# The name of the attribute that holds the relative
# distinguished name of each entry.
rdn: uid
# The name of the attribute that shall be used for the value of
# the metadata.name field of the entity.
name: uid
# The name of the attribute that shall be used for the value of
# the metadata.description field of the entity.
description: description
# The name of the attribute that shall be used for the value of
# the spec.profile.displayName field of the entity.
displayName: cn
# The name of the attribute that shall be used for the value of
# the spec.profile.email field of the entity.
email: mail
# The name of the attribute that shall be used for the value of
# the spec.profile.picture field of the entity.
picture: <nothing, left out>
# The name of the attribute that shall be used for the values of
# the spec.memberOf field of the entity.
memberOf: memberOf

groups组块定义了对组的读取和解释进行治理的设置。 其字段将在下面的章节中分别说明。

groups.dn

存储组的 DN,例如ou=people,ou=example,dc=example,dc=net.

groups.options

读取所有组时,向服务器发送查询时使用的搜索选项。 所有选项的默认值如下所示,但它们都是可选的。

options:
# One of 'base', 'one', or 'sub'.
scope: one
# The filter is the one that you commonly will want to specify explicitly. It
# is a string on the standard LDAP query format. Use it to select out the set
# of groups that are of actual interest to ingest. For example, you may want
# to filter out disabled groups.
filter: (&(objectClass=some-group-class)(!(groupType=email)))
# The attribute selectors for each item, as passed to the LDAP server.
attributes: ['*', '+']
# This field is either 'false' to disable paging when reading from the
# server, or an object on the form '{ pageSize: 100, pagePause: true }' that
# specifies the details of how the paging shall work.
paged: false

groups.set

这个可选项可让您指定一些 JSON 路径(a.b.c 格式)以及要在这些路径上设置的硬编码值。 例如,如果您想在生成的实体上硬编码命名空间或类似内容,这将非常有用。

set:
# Just an example; the key and value can be anything
metadata.namespace: 'ldap'

groups.map

从众所周知的实体字段到 LDAP 属性名称的映射。 在这里,您可以定义如何解释每个 LDAP 结果项的属性,并将它们移到相应的实体字段中。 下面显示了所有选项的默认值,但它们都是可选的。

如果您省略了可选映射,则仍会使用默认值进行复制。displayName在配置中,提供程序仍会复制属性cn输入实体字段spec.profile.displayName如果目标字段是可选的,如显示名称,导入程序将接受缺失的属性,只保留未设置的目标字段。 如果目标字段是必选的,如实体名称,如果缺少源属性,验证将失败。

map:
# The name of the attribute that holds the relative
# distinguished name of each entry. This value is copied into a
# well known annotation to be able to query by it later.
rdn: cn
# The name of the attribute that shall be used for the value of
# the metadata.name field of the entity.
name: cn
# The name of the attribute that shall be used for the value of
# the metadata.description field of the entity.
description: description
# The name of the attribute that shall be used for the value of
# the spec.type field of the entity.
type: groupType
# The name of the attribute that shall be used for the value of
# the spec.profile.displayName field of the entity.
displayName: cn
# The name of the attribute that shall be used for the value of
# the spec.profile.email field of the entity.
email: <nothing, left out>
# The name of the attribute that shall be used for the value of
# the spec.profile.picture field of the entity.
picture: <nothing, left out>
# The name of the attribute that shall be used for the values of
# the spec.parent field of the entity.
memberOf: memberOf
# The name of the attribute that shall be used for the values of
# the spec.children field of the entity.
members: member

自定义提供商

如果您想对接收到的实体进行自定义,提供程序允许为用户和组传递转换器。 下面我们将举例说明如何覆盖组转换器。

  1. Create a transformer: ts export async function myGroupTransformer( vendor: LdapVendor, config: GroupConfig, group: SearchEntry, ): Promise<GroupEntity | undefined> { // Transformations may change namespace, change entity naming pattern, fill // profile with more or other details... // Create the group entity on your own, or wrap the default transformer return await defaultGroupTransformer(vendor, config, group); } 2. Configure the provider with the transformer: ts const ldapEntityProvider = LdapOrgEntityProvider.fromConfig(env.config, { id: 'our-ldap-master', target: 'ldaps://ds.example.net', logger: env.logger, groupTransformer: myGroupTransformer, });

使用处理器而不是提供程序

除了使用提供程序摄取 LDAP 条目外,还有一种方法是使用处理器,这是一种老方法,它是通过注册具有适当类型和目标的位置来触发处理器运行的。

这种方法的缺点是,每当在 LDAP 服务器上删除组/用户实体时,都会留下孤儿实体,而且无法控制它们与其他处理器分开刷新的频率。

###处理器安装

LdapOrgReaderProcessor默认情况下没有注册,因此必须在目录插件中注册:

packages/backend/src/plugins/catalog.ts
builder.addProcessor(
LdapOrgReaderProcessor.fromConfig(env.config, {
logger: env.logger,
}),
);

利用位置驱动 LDAP 组织处理器输入

位置指出您要导入的特定 org。type这些地点必须ldap-orgtarget必须指向准确的 URL(以ldap://ldaps://如果需要,可以有多个这样的位置条目,但通常只有一个。

catalog:
locations:
- type: ldap-org
target: ldaps://ds.example.net
rules:
- allow: [User, Group]