随着企业业务场景的迫切需求的复杂化,传统的用户管理方式已经难以满足跨系统、多平台的身份。无论是企业的内部运营,还是面向客户的服务体系,都离不开高效、可靠的用户管理。用户目录不仅是一个简单的用户信息存储工具,更是企业实现认证、权限管理和安全保障的身份重要支撑。企业用户目录需要具备强大的扩展性和架构动态性变化的业务场景,支持多种认证协议以实现系统间的无缝集成,同时在安全性和灵活性上高效满足企业的定制化需求。如何构建和管理用户目录,已经成为企业提升生产力、强化安全防护和优化用户体验的关键。

01.企业遇到的问题

用户数据孤岛化

随着企业的业务拓展和系统数量的不断增加,用户数据孤岛化现象日益严重。许多企业在不同的业务系统中采用独立的用户管理模块,但各个模块内数据互不相同,导致用户在不同系统中的信息可能会出现不一致的情况。并且每个系统都有自己的一套用户信息维护,缺乏统一的标准和接口,导致不同系统间的数据无法有效同步和共享。例如,员工在某个系统中更新了个人数据,但其他系统中的数据没有及时同步更新,造成了信息失真。

用户界面需求丰富

在各行各业的企业对用户信息的需求存在着显著的差异,不同行业、不同场景的用户字段的需求各不相同。例如,金融行业可能需要用户的信用评分、交易记录等特定字段。而在医疗行业,用户的健康档案、就诊记录和医药这些行业特定的字段。但传统用户目录的字段是固定的,难以根据实际业务需求进行扩展,导致企业在管理用户数据时需要借助额外的工具和方法。在高度个性化和差异化的市场环境下,企业往往需要利用丰富的用户数据来做出精准决策和个性化服务。

登录配置缺乏灵活性

在某些情况下,部分企业针对特定群体或业务场景限制用户注册或访问权限,可能需要根据不同的用户角色、地域、设备、访问环境等因素,实施细粒度的访问控制和注册管理。企业可能需要根据特定的业务场景安全需求,快速调整用户的访问权限或者设置注册的某些特定条件,比如限制某些用户只能通过某种特定的认证方式登录,或者通过设置时间窗口来限制用户的访问权限。传统用户目录往往无法根据这些复杂条件灵活配置,导致管理员需要依赖额外的工具或手动操作,增加了系统管理的复杂性和人力成本。

02.Authing 用户目录助力企业实现高效身份管理

你可以把 Authing 用户目录理解为存储了你所有用户资料的目录,可以在用户目录中搜索用户、查看用户资料;以及对用户目录配置进行管理,如禁止注册、配置白名单等;这个用户目录的 Schema 是可扩展的,可以添加自定义的用户字段;同时你可以以多种标准协议(如 SAML、LDAP、OIDC、OAuth2.0)作为身份提供商(Identity Provider)对外提供身份认证能力。用户目录配置项
本文介绍用户目录相关的一些配置项,如禁止注册、频繁注册限制、登录失败次数限制、注册白名单等。

禁止注册

你可以在控制台的 安全设置->通用安全->注册安全 中开启 禁止注册 开关:


开启「禁止注册」之后,普通用户将无法通过登录表单或者 API 注册,只有管理员可以手动创建账号。

频繁注册限制

你可以在控制台的 安全设置->通用安全->注册安全 中开启 频繁注册限制 开关,限制在多少秒内不能超过多少次注册。

登录失败次数限制

你可以在控制台的 设置 - 安全信息 中开启 登录失败次数限制 开关,限制同一账号在多少秒内不能超过多少次失败登录。


若在规定时间内超过次数后,该用户再次登录需要输入图形验证码。


配置注册白名单

你可以在在控制台的 组织机构->注册白名单 中开启邮箱、手机号、用户名白名单,开启之后只有在白名单内的手机号、邮箱、用户名才能注册(管理员手动创建账号不受限制)。

禁止邮箱未验证的用户登录

默认情况下,未验证邮箱的账号可以进行登录,你也可以在 安全设置->通用安全->登陆安全 中修改此配置。

注册时发送欢迎邮件

关闭之后将不会发送欢迎邮件。你可以自定义欢迎邮件模版。


添加自定义用户字段
用户自定义字段是除了基础用户字段之外,可以给用户对象添加的额外字段。开发者可以通过设置自定义字段,存储少量业务相关的数据。

配置自定义用户字段

可以定义以下几种类型的自定义字段:字符串、数值、日期、布尔值、枚举值。你可以在设置 - 字段管理 - 用户扩展字段 页面配置自定义用户字段。


在给新创建的自定义字段命名时,你可以编辑该字段在多种语言环境下的显示名称:

1、直接在「显示名称」下的输入框中编辑,得到默认展示的字段名称
2、勾选「中文」,并编辑中文环境下的字段显示名称
3、勾选「English」,并编辑英文环境下的字段显示名称
3、勾选「繁體」,并编辑繁体中文环境下的字段显示名称
4、勾选「日本語」,并编辑日语环境下的字段显示名称

特别的,如果该字段的显示环境未包含在上述四种语言环境的范围内,将会采用你配置的「默认展示的字段名称」进行显示。配置自定义字段之后,你可以开启应用的注册信息补全页面,让用户补全这些自定义字段的信息。
在 应用详情 - 高级配置 页,开启 自定义本应用的登录框。


然后切换到 品牌化,勾上 开启注册信息补全 开关,然后选择刚刚添加的自定义字段。


数据类型 可以选择字符串、数字、布尔值、枚举值、日期,这会决定页面最终的展示样式。
点击保存,之后访问应用的登录页面。
用户点击注册之后将跳转到下面这个注册信息补全页面。
用户成功注册之后,你可以在用户详情页面看到用户刚刚输入的自定义字段值。

使用 API & SDK 管理用户自定义数据Authing 同时支持了 Java、JavaScript/Node.js、Python、PHP、C#、Swift、Go、Ruby、微信小程序等多种语言的 SDK,你可以选择自己熟悉的 SDK。

使用应用 ID(AppID) ,应用密钥(App Secret)和应用 Host(App Host)初始化 Java SDK 的 AuthenticationClient。

import cn.authing.core.auth.AuthenticationClient;// 使用 AppId, App Secret 和 AppHost 进行初始化AuthenticationClientOptions options = new AuthenticationClientOptions();

首先使用用户的 token 初始化 SDK。

authenticationClient.setAccessToken("ID_TOKEN");

设置自定义字段。

List<UserDefinedData> list = authenticationClient.setUdv('school', '华中科技大学').execute();

获取该用户最新的自定义数据。

List<UserDefinedData> list = authenticationClient.listUdv().execute();

搜索用户
Authing 支持通过邮箱、用户名、手机号、昵称等字段对用户进行模糊搜索,且同时支持控制台和 SDK 两种模式。

使用控制台搜索

你可以在 用户管理 - 用户列表 页面通过关键词搜索用户。


支持搜索的字段有邮箱、用户名、手机号、昵称等。

使用 SDK 搜索

Authing 同时支持了 Java、JavaScript/Node.js、Python、PHP、C#、Swift、Go、Ruby、微信小程序等多种语言的 SDK。 你可以使用各语言的用户管理模块(UsersManagementClient)的搜索用户方法。

使用 Authing 的 Cloud LDAP 用户目录

Authing 支持使用 LDAP 协议查看、修改、增加和删除用户信息。

版本说明
基于 OpenLDAP 实现的 Authing LDAP 2.0 于 2023 年 4 月 12 日发布,推荐使用 Authing LDAP 2.0 版本;使用 LDAP 2.0,你需要先启用身份自动化;如果你还需要使用旧版 LDAP,仍可以参考 LDAP 1.0。要了解 LDAP 1.0 与 2.0 的区别,可以查看(LDAP 1.0 和 LDAP 2.0 的差异)。

迁移至 LDAP 2.0

LDAP 1.0 和 LDAP 2.0 的差异

DN 的区别:Authing LDAP 1.0 在目录结构上与 LDAP 2.0 存在一些差异,以下是 LDAP 1.0 的 DN 基本结构。

用户 DN
uid=USER_ID,ou=DEPARTMENT_NAME,o=ORG_NAME,ou=users,o=USER_POOL_ID,dc=authing,dc=cn
部门 DN
ou=DEPARTMENT_NAME,o=ORG_NAME,ou=users,o=USER_POOL_ID,dc=authing,dc=cn

用户 DN
LDAP 2.0 的 DN 基本结构如下:

用户 DN
cn=xxx,ou=DEPARTMENT_NAME,ou=DEPARTMENT_NAME,dc=DOMAIN1,dc=DOMAIN2,o=authing
部门 DN
ou=DEPARTMENT_NAME,ou=DEPARTMENT_NAME,dc=DOMAIN1,dc=DOMAIN2,o=authing

用户 DN
从上述两种 DN 可以看到以下区别:

  • Base DN 会有所区别,LDAP 1.0 的 Base DN由 ou=users,o=USER_POOL_ID,dc=authing,dc=cn 组成,LDAP 2.0 的 Base DN 由 dc=DOMAIN1,dc=DOMAIN2,o=authing 组成,DOMAIN1 和 DOMAIN2 是由你初始化 LDAP 时输入的域名拆分得来的。
  • LDAP 1.0 的用户 DN 的 RDN 是 uid=USER_ID,LDAP 2.0 的用户 DN 的 RDN 是 cn=xxx,xxx 的值由你在身份自动化的字段映射决定。

用户属性的区别:
在 LDAP 1.0 中搜索用户会返回 Authing 用户的所有基础属性和拓展字段,而 LDAP 2.0 中返回的用户属性完全由你在身份自动化的数据转换节点配置决定。
配置 LDAP
进入 组织机构 -> LDAP 菜单,点击「初始化 LDAP」。


在弹窗中输入你想设置的 LDAP 域名,并点击「初始化」,此域名最终会被用于生成你的 LDAP Base DN ,如输入的是 http://example.com,则最终生成的是 dc=example,dc=com,o=authing。


初始化完成后,LDAP 服务中还没有用户数据,Authing 会自动为你的 LDAP 服务创建工作流,用于将 Authing 的用户数据同步至 LDAP 服务中,你需要点击右上角的「自动化」按钮进入身份自动化界面进行配置。
目前 Authing 为你自动创建的工作流有三个:

LDAP 上游全量同步:用于将 LDAP 服务中的数据全量同步回 Authing 组织架构,若你不需要通过 LDAP 协议修改用户数据,建议关闭。

LDAP 下游全量同步:用于将 Authing 组织架构数据全量同步至 LDAP 服务,建议将其触发器设置为定时任务,首次初始化 LDAP 后,可以手动执行一次此工作流,以便将用户同步至 LDAP 服务。

LDAP 下游增量同步:用于将 Authing 组织架构数据增量同步至 LDAP 服务。

假如你想使用第三方的 LDAP 服务,可以修改 LDAP 配置节点中的账号连接。

使用 LDAP
以下会介绍 LDAP 的简单使用,所有涉及到 LDAP 搜索相关命令都使用 ldapsearch 工具进行演示。

连接信息

Authing LDAP 的基本连接信息可以在 LDAP 的目录配置界面获取,配置信息如下:

域名:即你输入的 LDAP 域名。

LDAP 链接:LDAP 服务的域名、端口等信息。

LDAPS 链接:使用 LDAPS 连接服务的域名、端口等信息。

Bind DN:用于连接至 LDAP 服务的账号。

Bind DN 密码:用于连接至 LDAP 服务的密码,无法手动修改,若需要修改,可点击「自动生成密码」,并保存。

Base DN:搜索 LDAP 的基本 DN。

Search
基于 Base DN 进行查找,返回结果包含用户数据,以及组织机构数据。-LLL 表示禁止输出与过滤条件不匹配的信息,如果不带此项,你将得到获取结果的条目数以及请求部分信息。

$ ldapsearch -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "LDAP_BIND_DN_PASSWORD" -LLL -b "LDAP_BIND_DN"

查询过滤(Search Filter)

基于 Base DN 进行查找并过滤,返回结果包含用户数据,以及组织机构数据。
有关过滤的所有功能,可以参考 RFC-2254。

相等
此项查找根据 cn 进行查找,因为组织机构不具有该属性,只有用户具有该属性,结果将会返回用户 cn 为 小白 的用户信息。

$ ldapsearch -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "LDAP_BIND_DN_PASSWORD" -LLL -b "LDAP_BIND_DN" -s sub '(cn=小白)'

不等
与不等类似,此项查找 LDAP 中具有 cn (用户名)属性,且属性值不为 U 的所有信息,因为组织机构不具有该属性,只有用户具有该属性,结果将会返回用户姓名不为 hahhaha 的条目信息(其实只有用户具有 cn 属性,所以结果全是用户信息)。

$ ldapsearch -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "BIND_DN_PASSWORD" -LLL -b "$LDAP_BIND_DN" -s sub '(!(cn=hahhaha))'

查找模式
base 模式(只查找 baseDN 信息)

dn: LDAP_BASE_DN
$ ldapsearch -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "LDAP_BIND_DN_PASSWORD" -b "LDAP_BIND_DN" -s base


one 模式(只查找 baseDN 信息下的子节点)

以上图为例,one 模式会查找BaseDN 及 BaseDN 子节点 并返回相关信息。

dn: LDAP_BASE_DN...属性相关信息...dn: cn=xxx,LDAP_BASE_DN...属性相关信息...dn: ou=xxx,LDAP_BASE_DN...属性相关信息...$ ldapsearch -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "LDAP_BIND_DN_PASSWORD" -b "LDAP_BIND_DN" -s one

sub 模式(查找 baseDN 信息下的所有节点)

以上图为例,sub 模式会查找BaseDN 和 BaseDN 下的所有节点 并返回相关信息。

dn: LDAP_BASE_DN...属性相关信息...dn: cn=xxx1,LDAP_BASE_DN...属性相关信息...dn: ou=xxx,LDAP_BASE_DN...属性相关信息...dn: cn=xxx2,o=develop,LDAP_BASE_DN...属性相关信息...$ ldapsearch -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "LDAP_BIND_DN_PASSWORD" -b "LDAP_BIND_DN" -s sub

返回结果过滤(只返回指定属性)

如果你使用过 SQL,此功能与 select 类似。不增加过滤结果可能是这样的:

dn: LDAP_BASE_DN;cn: testcn;

增加相关过滤条件,则结果是这样的

$ ldapsearch -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "BIND_DN_PASSWORD" -b "$LDAP_BIND_DN" -s sub dn cn

Add

创建一个名为 user.ldif 的文件然后复制以下内容进去。

dn: (cn = username), LDAP_BASE_DN;objectClass: authingUser;cn: username;

然后执行以下命令:
该操作会在 LDAP 服务 中新增一个 用户

$ ldapadd -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "BIND_DN_PASSWORD" -f ./user.ldif

若你在工作流中开启了 LDAP 上游同步,则会将此数据同步回 Authing 用户池。

Modify
创建一个名为 modify.ldif 的文件然后复制以下内容进去:

dn: cn=username, ou=xxx, LDAP_BASE_DNchangetype: modify

然后执行以下命令:
该操作会在 LDAP 服务 中根据 modify 中的 DN 查找相关用户信息,查找成功,则根据 changetype 选择操作 用户信息 ,信息 来自于 changetype 下面的信息。

$ ldapmodify -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "BIND_DN_PASSWORD" -f ./modify.ldif

若你在工作流中开启了 LDAP 上游同步,则会将此数据同步回 Authing 用户池。

Delete

该操作会在 LDAP 服务 中根据 DN 查找相关用户信息,查找成功,则进行删除,这是一个敏感操作。

$ ldapdelete -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "BIND_DN_PASSWORD" "cn=username, ou=xxx, LDAP_BASE_DN"

若你在工作流中开启了 LDAP 上游同步,则也会在 Authing 用户池中将此数据删除。

Other
compare
该操作用于判断 LDAP Server 目录树中 DN 值和 指定条目值 是否属于同一个条目,是则返回 true,否则返回 false 。

$ ldapcompare -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "BIND_DN_PASSWORD" "uid=uid,o=oid,LDAP_BASE_DN" "cn:xxx"

modifyDN
用于对 LDAP Server 中的 RDN 条目的修改, 可以从标准的条目信息输入, RDN 指 DN 的首项, 例如 "cn=oldUserName, o=Org_ID, LDAP_BASE_DN" "cn=newUserName" 中的 cn=oldUserName, 由于不管是 用户的 DN 还是 组织结构的 DN 相关信息多数都是 id 相关的值, 所以当你修改 cn=oldUserName 其实等同于修改用户名。

$ ldapmodrdn -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "BIND_DN_PASSWORD" "cn=oldUserName,o=Org_ID,LDAP_BASE_DN" "cn=newUserName"

whoami
用于验证 LDAP 服务器 的身份,输入正确绑定 DN 以及密码,会返回指定的信息,否则会提示 ldap_bind: invalid credentials(49) 错误,这一般由于 密码错误 造成的,请检查 对应的密码 及 绑定 DN 信息 即可。 返回信息 test@example.com。

$ ldapwhoami -H LDAP_SERVER_URL -x -D "LDAP_BASE_DN" -w "BIND_DN_PASSWORD"

LDAP 事件

如果你想在身份自动化中使用 LDAP 相关事件,可以在触发器中选择 LDAP 应用,之后即可选择事件。