Penpot 如何配置 OpenID Connect(OIDC)单点登录,包括角色与 scopes 设置
【免费下载链接】penpotPenpot: The open-source design platform for Product teams that need scalable collaboration.项目地址: https://gitcode.com/GitHub_Trending/pe/penpot
如果你的自托管 Penpot 实例需要接入企业统一的身份提供方(Okta、Azure AD 或任意实现 OIDC 协议的服务),你需要通过环境变量启用 OIDC 登录后端,并在 IdP 侧配置正确的回调地址。Penpot 自 1.5.0 版本起支持通用 OIDC 集成,后续版本陆续加入了 scopes 覆盖(1.6.0)、userinfo 属性映射(1.12.0)、从 token 读取用户信息(1.19.0)和 OIDC 注册开关(2.1.2)。完成本文后,用户点击登录页的 OIDC 按钮即可通过外部提供方完成认证,并可按角色和 scopes 约束允许登录的人群。
Penpot 的配置方式是:flag(功能开关,形如enable-login-with-oidc)配置在一个统一的列表中,无论它影响哪个服务;环境变量则按服务配置。OIDC 的所有环境变量都是 backend only,但 flag 需要加到全局的PENPOT_FLAGS中。官方 docker-compose 文件 顶部维护了公共 flag 列表(注释中已列出login-with-oidc)和PENPOT_PUBLIC_URI,在这两处修改是最常见的主路径。
准备:在 IdP 中登记回调地址
在改 Penpot 之前,先在身份提供方里登记 Penpot 实例的回调地址。当前版本的回调格式为(<your_domain>替换为你实例的公共域名,即PENPOT_PUBLIC_URI指向的域名):
https://<your_domain>/api/auth/oidc/callback需要注意一个版本边界:从 2.12.0 起,SSO/OAuth 回调端点从旧格式/api/auth/oauth/<oauth_provider>/callback变更为上述统一格式(见 CHANGES.md 中 2.12.0 的 "Updated SSO Callback URL" 条目)。如果你已经在用旧版 Penpot 配置过 SSO,升级到 2.12.0 之前必须先在 IdP 侧把回调 URL 改成新格式,否则升级后认证会失败。
启用 OIDC 登录并填入 provider 凭证
最小可用的配置如下(均配置在 backend 的环境变量中,flag 加进PENPOT_FLAGS列表):
PENPOT_FLAGS: [...] enable-login-with-oidc # Backend PENPOT_OIDC_CLIENT_ID: <client-id> # Mainly used for auto discovery the openid endpoints PENPOT_OIDC_BASE_URI: <uri> PENPOT_OIDC_CLIENT_SECRET: <client-secret>PENPOT_OIDC_BASE_URI主要用于通过标准的 OpenID Connect discovery 机制自动发现协议端点;- 官方文档给出了 Azure Active Directory 的具体示例,
<tenant-id>替换为你的租户 ID:
# Backend & Frontend PENPOT_OIDC_CLIENT_ID: <client-id> # Backend PENPOT_OIDC_BASE_URI: https://login.microsoftonline.com/<tenant-id>/v2.0/ PENPOT_OIDC_CLIENT_SECRET: <client-secret>配置完成并重启实例后,登录页会出现 OIDC 登录按钮(按钮文案默认是 "OpenID")。
端点自动发现不够用时:手动覆盖端点与 SSRF 白名单
在自托管的容器化部署中,自动发现的端点不一定够:有些 provider 对浏览器暴露公共域名,而 Penpot backend 需要通过容器内部可解析的主机名访问同一服务。此时用下面这些可选变量显式覆盖端点,让浏览器走公共授权端点、backend 走内部可达的 token / userinfo / JWKS 端点:
# Optional backend variables, used mainly if you want override; they are # autodiscovered using the standard openid-connect mechanism. PENPOT_OIDC_AUTH_URI: <uri> PENPOT_OIDC_TOKEN_URI: <uri> PENPOT_OIDC_USER_URI: <uri> PENPOT_OIDC_JWKS_URI: <uri>另外,如果 backend 需要通过一个尚未被 SSRF 保护允许的主机名联系 OIDC provider(例如内部主机名与公共主机名不同),要把该主机名加入白名单,空格分隔:
# Backend # Space separated list of allowed hosts PENPOT_SSRF_ALLOWED_HOSTS: "<internal-provider-host> <public-provider-host>"文档指出这正是「浏览器通过公共 URL 可达、backend 通过不同内部主机名可达」场景下的常见需求。
配置角色(roles)检查
如果希望只有具备特定角色的用户才能登录,配置以下两个可选变量(backend only):
# Optional list of roles that users are required to have. If no role # is provided, roles checking disabled. PENPOT_OIDC_ROLES: "role1 role2" # Attribute to use for lookup roles on the user object. Optional, if # not provided, the roles checking will be disabled. PENPOT_OIDC_ROLES_ATTR:PENPOT_OIDC_ROLES是空格分隔的角色列表(示例值role1 role2来自文档),用户必须拥有其中声明的角色;PENPOT_OIDC_ROLES_ATTR指定在用户对象上查找角色的属性名;- 二者均为可选:未提供角色列表、或未提供属性名时,角色检查都会被关闭,即默认不做角色限制。
覆盖 scopes 与 userinfo 属性映射
默认情况下 Penpot 请求openid profilescopes。自 1.6.0 起,可以用PENPOT_OIDC_SCOPES覆盖所需的 scopes:
# This settings allow overwrite the required scopes, use with caution # because Penpot requires at least `name` and `email` attrs found on the # user info. Optional, defaults to `openid profile`. PENPOT_OIDC_SCOPES: "scope1 scope2"这是文档明确标注 "use with caution" 的项:Penpot 要求 userinfo 中至少能找到name和email两个属性。另外从 CHANGES.md 可知,PENPOT_OIDC_SCOPES的语义在 1.5.4 发生过一个 breaking change:它从「追加到默认集」改为「整体替换默认集」,配置时不要假设旧的追加行为。
如果 provider 在 userinfo 里用非标准的属性名存放姓名和邮箱,自 1.12.0 起可以映射属性名,未设置时默认使用name和email属性:
# Attribute to use for lookup the name on the user object. Optional, # if not provided, the `name` prop will be used. PENPOT_OIDC_NAME_ATTR: # Attribute to use for lookup the email on the user object. Optional, # if not provided, the `email` prop will be used. PENPOT_OIDC_EMAIL_ATTR:自 1.19.0 起还支持直接从 token 中读取用户信息,而不必请求 userinfo 端点(降低延迟,并兼容一些只在 token 中暴露 claims 的 provider):
# Set the default USER INFO source. Can be `token` or `userinfo`. By default # is unset (both will be tried, starting with token). PENPOT_OIDC_USER_INFO_SOURCE:可选开关:OIDC 注册与按钮文案
# 自 2.1.2:允许用户不先通过其他方式注册,直接以 OIDC 注册并登录 PENPOT_FLAGS: [...] enable-oidc-registration# 自 2.16.0(Frontend):自定义 OIDC 登录按钮上的显示名称,默认为 "OpenID" PENPOT_OIDC_NAME: <provider-name>如果目标是让 OIDC 成为唯一登录方式,官方 配置文档 在 "Other flags" 一节还列出了disable-login-with-passwordflag,可关闭基于密码的登录表单;与 OIDC 相关的默认状态是:注册默认启用 email/password 方式,其余认证后端(OIDC 在内)默认全部关闭。
登录流程与结果验证
配置正确与否,可以通过文档描述的 OIDC 后端流程来判断(见 authentication 子系统文档):
- 用户点击 "Log in with XXX" 按钮,frontend 调用
/auth/oauth/:provider,生成 request token 并把你重定向到身份提供方认证; - 认证成功后,provider 重定向回 Penpot 的回调地址;该处理用 request token 校验请求,从授权响应中提取 access token,再用它向 provider 请求 email 和 full name;
- 随后 Penpot 判断该 profile 是否已存在:已存在则直接打开一个 session(登录成功),不存在则走注册流程创建用户(是否允许由
enable-oidc-registration等配置决定)。
也就是说,验证方式是端到端的:配置好回调地址与凭证后,用具备所需角色的账号走一遍登录,能顺利被重定向回 Penpot 并进入已登录状态即为成功。若角色检查已启用而用户角色不符,则登录不会通过。
相关文档
- docs/technical-guide/configuration.md:全部 OIDC 环境变量的权威出处(Auth Providers → OpenID Connect 一节);
- docs/technical-guide/developer/subsystems/authentication.md:OIDC 后端的请求流程与端点发现机制;
- docker/images/docker-compose.yaml:官方 compose 文件中 flag 与公共变量的位置;
- CHANGES.md:2.12.0 回调 URL 变更与 1.5.4
PENPOT_OIDC_SCOPES语义变更的记录。
【免费下载链接】penpotPenpot: The open-source design platform for Product teams that need scalable collaboration.项目地址: https://gitcode.com/GitHub_Trending/pe/penpot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考