Harbor LDAP 模式下非管理员用户多项目创建与分页功能验证指南
2026/9/10 15:52:50 网站建设 项目流程

Harbor LDAP 模式下非管理员用户多项目创建与分页功能验证指南

【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor

导读

本文档对应 Harbor 仓库中的功能验证用例 2-13-LDAP-user-push-multiple-projects.md,核心目的是验证在 LDAP/AD 认证模式下(auth_mode=ldap_auth),非管理员用户能否创建多个项目,并验证项目列表的分页与搜索功能是否正常工作。读完本文,你将掌握 LDAP 模式下多项目创建验证的完整环境准备、操作步骤与预期结果判定方法,同时理解 Harbor 底层 LDAP 认证、项目公开性与分页查询的实现原理,便于自行设计同类回归测试。


一、测试目标与适用场景

本用例归属于tests/testcases/Group2-image-management测试套件,该套件系统性地覆盖了 Harbor 镜像管理领域的核心用户场景,包括:

用例主题认证模式
2-01创建项目DB(本地数据库)
2-03创建多个项目DB
2-11创建项目LDAP
2-12推送多个镜像LDAP
2-13(本文)创建多个项目LDAP
2-14查看项目LDAP

本用例与 2-03 的唯一区别在于用户来源:2-03 中用户由 Harbor 本地数据库管理(db_auth),而本用例中用户数据存储在 LDAP/AD 服务器中(ldap_auth)。这决定了该用例的验证重点是:LDAP 用户经 Harbor 认证"上船"(onboard)后,其身份权限模型与本地用户完全一致,应具备同等的项目创建能力

为什么要单独验证 LDAP 模式

从 src/core/auth/ldap/ldap.go 的实现可以看到,LDAP 用户登录时与本地用户有一个关键差异:LDAP 用户通过绑定(Bind)方式在 LDAP 服务器上完成密码校验,成功后 Harbor 会在本地数据库中插入一条"虚拟"用户记录,以便将用户与项目、成员、角色等实体关联。这个流程由PostAuthenticateOnBoardUser完成(ldap.go 中的OnBoardUser会为 LDAP 用户生成随机密码并标记Comment = "from LDAP.",密码本身不保存在本地库中)。

因此,本用例本质上是在验证这条"LDAP 校验 + 本地关联"链路在创建项目、分页浏览、关键词搜索等操作下是否稳定可靠。


二、环境准备(Environment)

依据原文档,执行本用例需要满足以下前提条件:

  1. Harbor 实例正在运行且可访问
  2. Harbor 配置为向 LDAP/AD 服务器进行认证,即auth_mode设置为ldap_auth,用户数据存储在 LDAP/AD 服务器中。
  3. 一台安装了 Docker CLI 的 Linux 主机(作为 Docker 客户端)。
  4. 至少一个非管理员用户(本文以"用户 A"代称,实际使用时应替换为更有意义的长名称)。

注:与原文档保持一致,LDAP 模式下该用例只要求"至少一个非管理员用户"即可完成多项目创建验证,无需像 2-11 那样准备两个用户。

2.1 认证模式常量的源码确认

在 src/common/const.go 中可找到认证模式的常量定义:

LDAPAuth = "ldap_auth"

Harbor 的认证助手通过auth.Register机制注册,ldap.go 末尾的init()函数完成注册:

func init() { auth.Register(common.LDAPAuth, &Auth{ userMgr: user.New(), }) }

这意味着当系统配置auth_mode=ldap_auth时,登录请求会路由到ldap.Auth实现,使用 LDAP 服务器完成身份校验。

2.2 LDAP 登录认证链路

ldap.go 中的Authenticate方法描述了完整链路,这也是本用例能执行的前提:

  1. 校验用户名非空;
  2. 加载系统 LDAP 配置并建立会话(ldapCtl.Ctl.Session+Session.Open);
  3. 在 LDAP 中搜索用户(SearchUser),要求恰好命中一条记录,否则分别报Not found an entry/Multiple entries found
  4. 使用用户 DN 与密码向 LDAP 服务器执行 Bind 校验;
  5. 校验通过后,将用户名、真实姓名、邮箱写入models.User
  6. 从本地数据库同步SysAdminFlag,并附加 LDAP 用户组信息(含组管理员 DN 识别、ldap_group_search_filter配置的组成员填充);
  7. 返回用户模型,交由后续的PostAuthenticate完成 onboard。

值得注意的细节:attachLDAPGroup中会判断该用户所属组是否等于配置的group_admin_dn,若命中则设置AdminRoleInAuth = true——这也是 LDAP 模式下组管理员与系统管理员角色识别的关键逻辑。若 LDAP 组搜索过滤器为空则跳过组填充,不会阻塞用户登录。


三、测试步骤(Test Steps)

原文档指出"操作步骤与 2-03 相同,仅用户来自 LDAP/AD"。为便于独立执行,下面将 2-03-DB-user-push-multiple-projects.md 的完整步骤迁移到 LDAP 场景,并补充验证要点:

  1. 以非管理员用户 A 登录 Harbor UI(用户 A 必须来自 LDAP/AD,且通过 LDAP 认证成功 onboard)。
  2. 创建 16 个或更多项目,使项目列表出现多页分页。创建项目时可采用默认配置(公开性关闭,即私有项目)。
  3. 在多页列表间翻页浏览,并点开若干项目查看详情,验证分页控件工作正常。
  4. 使用关键词搜索项目,验证列表与分页是否随搜索结果同步更新。

原文提示:文中的"用户 A""项目 X/Y"等占位名称,实际执行时应替换为更长、更有辨识度的名称,避免与真实数据混淆。

3.1 步骤要点解析

步骤 2 的关键在于"量":只有项目数量超过单页容量(Harbor 项目列表 API 默认按page/page_size参数分页)才会出现多页,因此要求创建 16 个以上项目以覆盖至少两页。这一步同时验证了 LDAP 用户连续创建多个项目的权限与配额是否正常。

步骤 4 的关键在于"搜索与分页联动":输入关键词后,列表应只展示匹配项目,且分页总页数应基于过滤后的总数重新计算——这要求服务端先按关键词过滤、再分页返回,而不是在前端做简单过滤。

3.2 使用 REST API 辅助验证(可选)

除了 UI 操作,还可以通过 Harbor v2.0 API 直接验证分页与搜索行为。项目列表接口对应的服务端实现位于 src/server/v2.0/handler/project.go,其关键调用链为:

query, err := a.BuildQuery(ctx, params.Q, params.Sort, params.Page, params.PageSize) ... WithLink(a.Links(ctx, params.HTTPRequest.URL, total, query.PageNumber, query.PageSize).String()).

对应可构造如下请求:

# 不带筛选,看第 1 页,每页 10 条 curl -u "<userA>:<password>" \ "https://<harbor_host>/api/v2.0/projects?page=1&page_size=10" # 按关键词过滤,同时观察分页 curl -u "<userA>:<password>" \ "https://<harbor_host>/api/v2.0/projects?q=name=~<keyword>&page=1&page_size=10"

其中q参数的模糊匹配语法(name=~keyword)来自 src/lib/q/builder.go,该文件定义了完整的查询语法:精确匹配k=v、模糊匹配k=~v、区间k=[min~max]、或列表k={v1 v2 v3}、与列表k=(v1 v2 v3)


四、预期结果(Expected Outcome)

与原文档及 2-03 一致,本用例的预期结果如下:

  • 步骤 3:分页控件正常工作,LDAP 用户 A 可以在多页之间自由翻页,点开各项目详情均可正常查看;
  • 步骤 4:关键词搜索后,列表与分页同步更新,仅显示匹配搜索条件的项目,且分页总数基于过滤结果正确计算。

也就是说:LDAP 模式下的非管理员用户应拥有与 DB 模式用户完全一致的多项目创建、浏览与搜索能力


五、源码级原理:这些行为在 Harbor 中如何实现

5.1 项目创建与公开性(Publicity)

项目模型定义在 src/pkg/project/models/project.go,其中:

  • 项目公开性通过元数据键public存储,常量ProjectPublic/ProjectPrivate分别对应"public"/"private"
  • IsPublic()读取public元数据并判断是否为 true(字符串"true""1"均视为 true);
  • FilterByPublic通过子查询SELECT project_id FROM project_metadata WHERE name = 'public' AND value = '...'实现公开项目过滤。

项目控制器 src/controller/project/controller.go 对外暴露CreateListCountListRoles等操作,其中ListRoles用于查询用户在某项目中的角色,非管理员用户创建项目后会自动成为该项目管理员(项目所有者)。

5.2 分页与排序的实现

Harbor 的统一分页机制位于 src/lib/q/builder.go 的Build函数:

// Build query sting, sort and pagination information into the Query model // query string format: q=k=v,k=~v,k=[min~max],k={v1 v2 v3},k=(v1 v2 v3) func Build(q, sort string, pageNumber, pageSize int64) (*Query, error)

它将查询串、排序串、页码与页大小统一封装为Query模型(含KeywordsSortsPageNumberPageSize)。排序语法支持sort=k1,-k2(前缀-表示降序)。

服务端处理器通过 src/server/v2.0/handler/base.go 中的BuildQuery组装查询,并用Links方法基于总数、页码、页大小生成上一页/下一页的导航链接——这正是 UI 分页控件的数据来源:

// BuildQuery builds the query model according to the query string func (b *BaseAPI) BuildQuery(_ context.Context, query, sort *string, pageNumber, pageSize *int64) (*q.Query, error) { ... return q.Build(qs, st, pn, ps) }

结合 src/server/v2.0/handler/project.go 的调用点(第 318、346 行等)可以确认:项目列表 API 先过滤(q)、再排序(sort)、后分页(page/page_size),并基于总数生成分页链接。这从底层印证了"关键词搜索后分页同步更新"的预期行为是服务端语义,而非前端实现。

5.3 LDAP 用户与本地权限模型的统一

本用例之所以能与 DB 模式用例"共用步骤",其根本原因在于:LDAP 用户登录成功后,Harbor 通过OnBoardUser在本地用户表中建立映射记录(密码为随机字符串、备注from LDAP.),后续所有权限判断(项目创建、成员关系、角色分配)均基于本地用户 ID 进行。因此从项目控制器的视角看,LDAP 用户与 DB 用户没有区别——这正是测试套件中 DB 用例与 LDAP 用例成对出现、步骤互引的设计动机。


六、常见问题与排查建议

原文档"Possible Problems"一节为空(None),但根据源码可以预判并排查以下潜在问题:

现象可能原因排查方向
用户无法登录LDAP 配置错误、搜索命中多条记录检查ldap_urlldap_base_dnldap_uid配置;查看 ldap.go 中Authenticate对"多条记录"的报错
登录成功但无法创建项目系统配置中限制了普通用户创建项目(如project_creation_restriction),或用户未被正确 onboard确认系统设置中的项目创建权限;检查用户表中是否存在Comment = "from LDAP."的映射记录
分页/搜索结果与预期不符服务端q参数语法错误参照 src/lib/q/builder.go 的语法规则构造查询
LDAP 用户被识别为系统管理员用户属于group_admin_dn配置的组,AdminRoleInAuth被置为 true检查attachLDAPGroup逻辑与组管理员配置

七、结语

本用例以极简的方式验证了一个关键的产品承诺:无论用户来自本地数据库还是 LDAP/AD,Harbor 都向非管理员用户提供一致的多项目创建、分页浏览与搜索能力。它作为 Group2 镜像管理测试套件中 LDAP 链路的一环,与 2-11(创建单个项目)、2-12(推送多个镜像)、2-14(查看项目)共同构成了 LDAP 模式下镜像管理主链路的完整回归覆盖。测试人员可将本文步骤作为模板,结合自身 LDAP 目录结构扩展更多项目数量与搜索关键词,以覆盖边界场景。

【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询