OpenProject 开发实战:用 Docker 容器化 SAML idP 快速搭建本地 SSO 联调环境

发布时间:2026/9/14 16:30:27
OpenProject 开发实战:用 Docker 容器化 SAML idP 快速搭建本地 SSO 联调环境 OpenProject 开发实战用 Docker 容器化 SAML idP 快速搭建本地 SSO 联调环境【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject本文聚焦 OpenProject 官方开发文档中的 SAML 开发环境搭建指南如何在本地开发实例中用容器化的 SimpleSAMLphp 身份提供商idP完成 SAML SSO 的端到端联调。读完后你将掌握users.php属性配置、docker 环境变量SP Entity ID、ACS 回调地址、SLO 地址的完整含义、configuration.yml中 SAML 各配置项与 OpenProject 源码字段的对应关系并能用两个内置测试账号验证登录与登出全流程。一、这份指南的适用范围该指南docs/development/saml/README.md明确指出仅面向 OpenProject 开发者本地联调不是生产环境的 SAML 接入指南。生产/管理侧的 SAML 配置请参见 系统管理员 SAML 文档。核心思路是使用现成的测试 idP 镜像kristophjunge/test-saml-idp内含 SimpleSAMLphp通过挂载自定义authsources.php补充 OpenProject 期望接收的属性再以 OpenProject 作为 SP服务提供方完成标准 SAML 2.0 断言流程。前置条件一套可用的 Docker 环境一套可自由修改配置的 OpenProject 开发实例。二、编写补充属性的 users.php容器内自带的 SimpleSAMLphp 默认用户配置缺少 OpenProject 需要的一批默认属性因此官方指南要求在本地新建一个saml-idp目录并写入如下users.php该文件稍后会挂载为容器内的authsources.php?php $config array( admin array( core:AdminPassword, ), example-userpass array( exampleauth:UserPass, user1:user1pass array( uid user1, givenName foo, sn bar, eduPersonAffiliation array(group1), email user1example.com, ), user2:user2pass array( uid user2, givenName user, sn second, eduPersonAffiliation array(group2), email user2example.com, ), ), );这里为两个测试账号user1/user1pass、user2/user2pass分别声明了uid、givenName、sn、eduPersonAffiliation、email五类属性。这些属性名并非随意命名——它们正是 OpenProject 侧 SAML 属性映射的默认取值。从源码看默认映射常量 中内置了邮箱mail/email/emailAddress等、名字givenName等、姓氏sn/surname等的候选属性列表开发文档中的attribute_statements也是按uid → login、givenName → first_name、sn → last_name、email → email来映射的二者完全吻合这也是默认用户配置缺属性就收不到用户这一说法的直接来源。三、启动 SAML idP 容器在saml-idp目录中执行本机开发环境OpenProject 运行在localhost:3000mkdir saml-idp cd saml-idpdocker run \ -p 8080:8080 \ -p 8443:8443 \ -e SIMPLESAMLPHP_SP_ENTITY_IDhttp://localhost:3000 \ -e SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICEhttp://localhost:3000/auth/saml/callback \ -e SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICEhttp://localhost:3000/auth/saml/slo \ -v $(pwd)/users.php:/var/www/simplesamlphp/config/authsources.php \ --network host \ kristophjunge/test-saml-idp如果不是标准开发实例需要把三个环境变量中的http://localhost:3000替换为你的 OpenProject 实际主机名docker run \ -p 8080:8080 \ -p 8443:8443 \ -e SIMPLESAMLPHP_SP_ENTITY_IDhttp://YOUR OPENPROJECT HOSTNAME \ -e SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICEhttp://YOUR OPENPROJECT HOSTNAME/auth/saml/callback \ -e SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICEhttp://YOUR OPENPROJECT HOSTNAME/auth/saml/slo \ -v $(pwd)/users.php:/var/www/simplesamlphp/config/authsources.php \ --network host \ kristophjunge/test-saml-idp各参数含义结合源码印证参数含义-p 8080:8080idP 的 HTTP SSO 入口对应下文 SP 配置中的idp_sso_target_url-p 8443:8443idP 的 HTTPS 端口SimpleSAMLphp 默认启用 TLS 演示SIMPLESAMLPHP_SP_ENTITY_ID告诉 idPSP 的 Entity ID 是什么。对应 OpenProject 的sp_entity_id/issuer字段SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE断言回调地址ACS即 OpenProject 的/auth/saml/callback。源码中该地址由AuthProvider#callback_url生成Saml::Provider 通过assertion_consumer_service_url委托给callback_url提供SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE单点登出SLO地址/auth/saml/slo-v $(pwd)/users.php:/var/www/simplesamlphp/config/authsources.php用自定义用户/属性配置覆盖容器默认的 authsources--network host直接使用宿主机网络保证localhost可达四、在 configuration.yml 中配置 OpenProject 侧 SAML在 OpenProject 的config/configuration.yml中加入如下最小配置完整示例可参考 config/configuration.yml.exampledefault: saml: name: saml display_name: simplesaml-docker # 使用默认 SAML 图标 icon: auth_provider-saml.png # omniauth-saml 配置 assertion_consumer_service_url: http://localhost:3000/auth/saml/callback issuer: http://localhost:3000 idp_cert_fingerprint: 119b9e027959cdb7c662cfd075d9e2ef384e445f idp_sso_target_url: http://localhost:8080/simplesaml/saml2/idp/SSOService.php idp_slo_target_url: http://localhost:8080/simplesaml/saml2/idp/SingleLogoutService.php attribute_statements: email: [email] login: [uid] first_name: [givenName] last_name: [sn]逐项说明name/display_namename是内部标识用于生成/auth/saml这类 OmniAuth 路由前缀display_name是登录页上显示的名称。重启后登录按钮即显示为 simplesaml-dockerassertion_consumer_service_urlSP 接收断言的回调 URL必须与容器侧SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE完全一致issuerSP Entity ID对应容器侧的SP_ENTITY_IDidp_cert_fingerprint测试 idP 证书的 SHA-1 指纹。注意 OpenProject 同时支持完整证书 PEM——Saml::Provider 中idp_cert是首选字段idp_cert_fingerprint仅作为旧版本的回退兼容保留UI 上已不再提供指纹入口idp_sso_target_urlidP 的 SSO 入口即容器 8080 端口下的SSOService.phpidp_slo_target_urlidP 的单点登出入口SingleLogoutService.phpattribute_statements声明OpenProject 需要的字段 ← idP 断言中的哪个属性的映射与users.php中的属性名一一对应。从源码结构看configuration.yml中的这些键最终会被 HashBuilder#to_h 转换为 omniauth-saml 的策略参数attribute_statements经formatted_attribute_statements拆分支持多属性候选按换行分隔、idp_cert_fingerprint/idp_cert经idp_cert_options_hash决定用证书还是指纹校验再合并security_options_hash签名/摘要算法、want_assertions_signed等后交给 omniauth-saml 使用。如果你的 OpenProject 不跑在localhost:3000需要把assertion_consumer_service_url、issuer换成本机实际主机名如果 idP 不在本机idp_sso_target_url、idp_slo_target_url也要同步调整。官方建议两端都放本地最省事。五、验证登录与底层调用链重启 OpenProject 后登录页会出现名为 simplesaml-docker 的按钮点击后被重定向到 SimpleSAMLphp 容器使用以下任一账号登录登录名user1密码user1pass登录名user2密码user2pass。登录成功的背后调用链在 AuthSaml 引擎注册代码 中可以看到每个可用 provider 的配置被转换为一个 omniauth-saml 策略retain_from_session会把saml_uid、saml_session_index、saml_transaction_id暂存会话供后续登出使用single_sign_out_callback则检查会话中是否存在这两个字段存在时恢复它们并重定向到omni_auth_start_path(...)/spslo从而走 SP 发起的 SLO 流程——这解释了为什么idp_slo_target_url和容器侧SP_SINGLE_LOGOUT_SERVICE两侧都要配置。另外两点值得注意的源码事实provider 的可用判定由 configured? 与 mapping_configured? 控制sp_entity_id、idp_sso_service_url、idP 证书或指纹齐备才算配置完成mapping_login/mail/firstname/lastname四项映射齐备才算映射完成。上面configuration.yml恰好把这三类字段配齐因此可直接通过该方式configuration.ymlseed适合开发环境产品化路径是在后台身份与访问 → SAML 提供方页面管理 provider对应路由见 modules/auth_saml/config/routes.rb并支持从 idP 的 metadata URL/XML 自动导入实体 ID、SSO/SLO 地址与证书相关服务位于 metadata_fetcher.rb 与 update_metadata_service.rb。开发文档走静态配置是为了最小化步骤两者殊途同归。六、常见问题速查现象排查点登录页没有 simplesaml-docker 按钮configuration.yml未重启生效或 provider 未通过configured?缺少 idP 证书/指纹断言 400/签名错误issuer与容器SP_ENTITY_ID不一致或idp_cert_fingerprint换证书后未更新登录成功但用户字段为空attribute_statements的属性名与users.php实际下发的属性不匹配登出后 idP 会话仍在检查idp_slo_target_url与SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE是否两侧对齐这套容器 idP 最小 YAML 配置的组合让你无需任何企业级 IdP 就能在本地完整复现 SAML 登录、属性映射与单点登出是开发 OpenProject 认证相关功能时最便捷的联调基座。【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考