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。
更新后端中的目录插件初始化,添加提供程序并进行调度:
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
自定义提供商
如果您想对接收到的实体进行自定义,提供程序允许为用户和组传递转换器。 下面我们将举例说明如何覆盖组转换器。
- 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
默认情况下没有注册,因此必须在目录插件中注册:
builder.addProcessor(
LdapOrgReaderProcessor.fromConfig(env.config, {
logger: env.logger,
}),
);
利用位置驱动 LDAP 组织处理器输入
位置指出您要导入的特定 org。type
这些地点必须ldap-org
和target
必须指向准确的 URL(以ldap://
或ldaps://
如果需要,可以有多个这样的位置条目,但通常只有一个。
catalog:
locations:
- type: ldap-org
target: ldaps://ds.example.net
rules:
- allow: [User, Group]