Skip to content

LDAP Viewer and LDAP 登录 - #6489

Open
idxdy wants to merge 19 commits into
t8y2:mainfrom
idxdy:feat/ldap
Open

LDAP Viewer and LDAP 登录#6489
idxdy wants to merge 19 commits into
t8y2:mainfrom
idxdy:feat/ldap

Conversation

@idxdy

@idxdy idxdy commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

背景

为 DBX 增加原生 LDAP 目录浏览与登录能力,并保持与现有数据库驱动、Web 认证体系和 MCP 工具一致的可扩展边界。交互研究参考了Apache Directory Studio, 以及本人常用的交互方式

有rust原生支持方式(simple bind), 也有JNDI/JAAS的接入方式(GSSAPI), rust 下的ldap库对GSSAPI支持比较麻烦, 为了保证跨平台和兼容性, GSSAPI认证方式, 使用了java agent方式接入

登录流程、前端组件与实现代码均按 DBX 现有设计体系独立完成。

主要变更

原生 LDAP 驱动与数据层

  • 新增原生 LDAP 驱动 ldap_driver.rs(基于 ldap3 crate),支持 simple bind 与搜索,暴露与既有 Java agent 一致的 JSON 输出形态(entries/dn/attributes/count/truncated)。
  • 新增 ldap_ops.rs 统一封装搜索与子节点列举(ldap_search_core / ldap_list_children_core),支持 base/one/sub scope、RFC 4515 过滤、属性白名单与 size_limit,并对 RFC 4514/4515 转义(DN 与 filter 注入防护)。
  • DatabaseType、连接模型、连接池、schema 能力、production-safety 等扩展点登记 LDAP,接入通用连接生命周期(测试/连接/断开/关闭)。
  • 集成测试支持通过 DBX_LDAP_INTEGRATIONDBX_LDAP_HOST/PORT/USER/PASSWORD/BASE_DN 指向本地 OpenLDAP 容器(deploy/database/ldap/compose.yml + ldif/1/1.ldif,含 alice/bob/charlie 与 developers/managers 组),默认即连接 compose 环境。
  • 会自动序列化GUID字段, 方便和其他系统集成, 比如Active Role

LDAP 登录(Web 认证)

  • 新增 ldap_login.rs 登录模块,支持两种模式:
    • NOSV(无服务账号):直接以用户输入绑定。Active Directory, 支持这种方式, 一般来说支持 domain\sAMAccountName, sAMAccountName, dn, mail + password, 具体支持情况需要咨询公司的AD team的开放情况
    • SV(服务账号):先用服务账号查询用户 DN,再以用户 DN + password 绑定。openldap, 389 Directory等客户端, search 规则, 可以自己配置
  • 配置经应用设置页持久化(LdapLoginSettings),服务账号密码以脱敏方式存储、redacted() 后回传,空白时保留已存密码。
  • /auth/ldap-login 登录接口与 /auth/checkldap_enabled 联动;登录页支持 LDAP / 密码两种模式切换。
  • LDAP 登录配置接口在 /app-settings/ldap-login(含 /test 用于连接测试),统一由 auth 中间件保护。
  • test_connection 在服务账号密码留空时复用已存密码,避免“密码未配置”误报。

MCP / AI 工具

  • MCP server 新增 dbx_execute_ldap_search 工具:connection_id/name + base_dn + filter + scope + attributes[] + size_limit,仅对 LDAP 连接可用,走核心 ldap_ops::ldap_search_core,只读。
  • dbx_add_connection 支持 LDAP 专属字段(ldap_security_protocolldap_principalldap_keytab_pathldap_krb5_confldap_base_dn),并补齐默认端口 ldap→389ldaps→636
  • 应用内 AI Agent 的 dbx_execute_ldap_search 工具与 MCP 工具共用同一执行路径。

Java Agent

  • 保留并完善 LdapAgent(JNDI) 作为可选实现;LdapAgentTest 集成测试默认指向本地 OpenLDAP 容器(simple bind),GSSAPI 测试移除(无 Kerberos 环境)。
  • GSSAPI认证(Kerberos), 在公司内部测试通过, 包含 UPN + password, UPN + keytab
  • 文档路线 D 的构建产物 dbx-agent-ldap.jar 可直接替换 ~/.dbx/agents/drivers/ldap/agent.jar

安全设计

  • 未提供写入功能, 理论上来说, 企业级别的管理最好通过第三方的管理工具, 比如Active Role来做, 好吧, 我没有这个需求
  • LDAP 搜索是只读操作:dbx_execute_ldap_search 与 Agent 工具均不提供写路径,也不执行任意命令。
  • filter / DN 值统一经 RFC 4515 / RFC 4514 转义,阻止过滤注入与 RDN 注入。
  • LDAP 登录服务账号密码不落前端、不回传明文,配置读取时脱敏。
  • MCP 与 Agent 执行均经过 auth_middleware / 连接 allowlist / 只读策略约束,无绕过前端的直通路径。
  • LDAP 集成测试数据仅含本地测试目录,不含生产凭据。

自审修复

  • 登录配置接口从 /auth/* 迁移到 /app-settings/ldap-login,避免配置接口与登录接口混在同一权限域。
  • /auth/check 移除冗余的 ldap_connections,仅保留 ldap_enabled,减少未登录环境的信息暴露。
  • 默认用户搜索过滤器补全 (uid={user}),真正覆盖 AD(sAMAccountName)与 OpenLDAP(uid)。
  • test_connection 复用已存服务账号密码,修复“配置保存后测试报密码未配置”。
  • Java LdapAgentTest 集成配置改为 env 可覆盖并默认指向 compose,移除依赖真实 AD 的 GSSAPI 用例。
  • MCP bin.test 修复 Windows 下 EBUSY 临时目录清理竞态(等待子进程退出后重试删除)。

变更类型

  • 新功能
  • Bug 修复
  • 性能优化
  • 代码重构
  • 文档更新
  • CI / 构建

涉及前端

  • 本 PR 涉及前端改动,已附截图/录屏(见下方)
config search simple bind nosv pic1 gssapi keytab gssapi pwd gssapi pwd1 dark

客户端

客户端_GSSAPI_PWD 客户端_ldap_simpleBind 客户端GSSAPI_keytab

DBX_DISABLE_PASSWORD=1, 开启 LDAP登录
LDAP only 受保护接口401

验证

  • make dev-fast / cargo check --no-default-features:全 workspace 通过。
  • cargo test --no-default-features -p dbx-core:3475 项通过、0 失败(含 LDAP 驱动集成测试、登录过滤转义、存储往返)。
  • LDAP 集成测试(DBX_LDAP_INTEGRATION=1):simple bind 连接/搜索/size limit/属性返回 4 项全过。
  • Java Agent :ldap:test:20 项通过(simple bind 指向本地 OpenLDAP 容器)。
  • MCP pnpm test:packages:CLI + MCP-server 全部通过;dbx_execute_ldap_search 对真实目录返回 DN/属性/组信息。
  • cargo test -p dbx-web:66 项通过。
  • 前端 pnpm typecheckpnpm lint 通过;pnpm test 5708 项通过(2 项为并行 mock 竞态,单独运行该文件 32/32 通过)。
  • cargo fmt --all -- --check:通过。

关联 Issue

Related #1647

测试环境

  • deploy/database/ldap/compose.yml 提供 mlan/openldap:latest 本地容器(默认端口 389/636,ldif/1/1.ldif 自动导入),用于驱动、Java Agent 与登录流程的真实验证;rootless podman 环境需 net.ipv4.ip_unprivileged_port_start=389
  • 公司内部真实测试环境, 包含Simple Bind和GSSAPI

@github-actions github-actions Bot added area/multiple Touches more than three repository areas db/multiple Touches more than three database integrations dependencies/backend Adds a backend dependency ui-change Changes user-visible interface, text, or visual assets labels Aug 17, 2026
@idxdy idxdy changed the title LDAP View LDAP Viewer and LDAP 登录 Aug 17, 2026

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request changes:这个 head 目前不能合并。请先 rebase/split 到当前 main;GitHub 显示 3,032 个变更文件且状态为 CONFLICTING,merge-base 仍停留在 2026-04-30。

另外有三个 blocker:

  1. apps/desktop/src/lib/backend/tauri.tsldapSearch() 始终抛错,而桌面运行时会选择 Tauri backend,导致 LDAP 树、详情和搜索在桌面端全部不可用。
  2. crates/dbx-web/src/auth.rsDBX_DISABLE_PASSWORD=1 时无条件放行 API;启用 LDAP 后登录页虽要求认证,未登录请求仍能直接访问受保护接口。
  3. agents/drivers/ldap/src/main/java/com/dbx/agent/ldap/LdapAgent.java 读取 use_ssl,Core 实际发送的是 ssl,所以 GSSAPI 的 LDAPS 配置不会生效;LDAP 连接表单也没有 TLS 开关。

修复后请补 Tauri Viewer、LDAP-only middleware 和 Core→Agent TLS 映射测试,并让 exact head 的 CI 完整通过。

@idxdy

idxdy commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

OK, 我处理一下

jaime.su added 3 commits August 20, 2026 14:36
Add LDAP as a first-class connection type in dbx-core:
- ldap3-based native driver (simple bind / anonymous) plus GSSAPI routing to the Java agent
- ldap_login (app-level LDAP login for the web backend) and ldap_ops (search dispatch)
- DatabaseType::Ldap + 5 ldap_* ConnectionConfig fields, pool/keepalive/health branches
- dbx-web: /ldap/search + /ldap/list-child routes, LDAP login backend, app-settings LDAP config
- storage: LDAP login settings round-trip (preserves password hash)
- agent tools: dedicated dbx_execute_ldap_search tool; LDAP excluded from SQL query paths
- LDAP browser + search components and sidebar entry tree (loadLdapRoot/loadLdapEntryChildren)
- ConnectionDialog LDAP form (simple bind / GSSAPI / anonymous, keytab + krb5.conf)
- LdapLoginSettings panel in editor settings; AppToolbar/AppTabBar LDAP-aware behavior
- QuickConnectionOpenTarget, tabPresentation and i18n (en/zh-CN) for ldap modes
- databaseNamespaceCreation / databasePropertyEditing mark LDAP as read-only browse
- api/http/tauri backend wiring for ldap search endpoints
- agents/drivers/ldap: JDBC-style Java agent for GSSAPI/Kerberos LDAP via JNDI+JAAS
- dbx-mcp: expose dbx_execute_ldap_search tool and LDAP connection options
- agents/settings.gradle: register the ldap driver module
- deploy/database/ldap: compose + ldif fixtures for local LDAP testing
@github-actions github-actions Bot added db/redis Database: Redis and removed db/multiple Touches more than three database integrations labels Aug 20, 2026
@idxdy

idxdy commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

先处理冲突问题, 之后的问题, 我会持续跟进

jaime.su added 16 commits August 20, 2026 21:20
- ldap_login: drop redundant map_err identity; use assert! for bool checks
- storage: use assert! for bool check in LDAP settings round-trip test
- dbx-mcp: allow clippy::too_many_arguments on new_connection_config_with_ldap
# Conflicts:
#	agents/settings.gradle
#	crates/dbx-core/Cargo.toml
# Conflicts:
#	agents/versions.json
#	apps/desktop/src/App.vue
#	apps/desktop/src/components/connection/ConnectionDialog.vue
#	apps/desktop/src/components/sidebar/SidebarTreeRuntimeHost.vue
#	apps/desktop/src/types/database.ts
#	crates/dbx-core/Cargo.toml
#	crates/dbx-core/assets/database-drivers.manifest.json
#	crates/dbx-core/src/agent_catalog.rs
#	crates/dbx-core/src/database_capabilities.rs
#	crates/dbx-core/src/models/connection.rs
#	crates/dbx-mcp/src/server.rs
@github-actions github-actions Bot added the db/duckdb Database: DuckDB label Aug 25, 2026
@idxdy

idxdy commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

apps/desktop/src/lib/backend/tauri.ts 的 ldapSearch() 始终抛错,而桌面运行时会选择 Tauri backend,导致 LDAP 树、详情和搜索在桌面端全部不可用。
crates/dbx-web/src/auth.rs 在 DBX_DISABLE_PASSWORD=1 时无条件放行 API;启用 LDAP 后登录页虽要求认证,未登录请求仍能直接访问受保护接口。

以上截图已补

agents/drivers/ldap/src/main/java/com/dbx/agent/ldap/LdapAgent.java 读取 use_ssl,Core 实际发送的是 ssl,所以 GSSAPI 的 LDAPS 配置不会生效;LDAP 连接表单也没有 TLS 开关。

simple bind 的ssl测试
agents\drivers\ldap\src\test\java\com\dbx\agent\ldap\LdapAgentTest.java::integrationSimpleBindOverLdapsSucceeds
deploy\database\ldap\compose.yml 已经补上ssl相关环境配置, 避免依赖我的内部环境

表单未加

最近比较忙, phase2 做

@eryajf

eryajf commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

从 ldap 管理维度,提一些个人测试的小建议。

  1. 界面应该增加一个刷新的按钮,以便查看新的数据
    同时下方这个截图中,组织内的用户展示方案可以优化一下,现在单行展示,用户过多之后,会有问题。
    image

  2. 资源右键不应该有打开连接,可以优化下

    image
  3. 当前资源好像都是只能查看?是否有计划完善增删改查几项能力?当然 object 比较多,可以优先考虑支持常见的几种。

  4. 这些地方看看是否可以识别,末级不应该再有展开按钮
    image

  5. 有无可能参照 ldapadmin 针对不同属性,展示不同的 icon
    image

PS:很棒的新增支持,我这些建议也许不用一直在这个PR 里实现,可先有查询可用的第一版,避免 PR 落后主分支太久。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/multiple Touches more than three repository areas db/duckdb Database: DuckDB db/redis Database: Redis dependencies/backend Adds a backend dependency ui-change Changes user-visible interface, text, or visual assets

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants