oauth2-proxy 集成 SourceHut 认证提供方:配置、自建实例与原理剖析
【免费下载链接】oauth2-proxyA reverse proxy that provides authentication with Google, Azure, OpenID Connect and many more identity providers.项目地址: https://gitcode.com/GitHub_Trending/oa/oauth2-proxy
SourceHut(sr.ht)是一个面向开发者的开源托管平台,其元服务meta.sr.ht提供标准 OAuth 2.0 认证能力。本文讲解如何让 oauth2-proxy 借助 SourceHut 账户完成反向代理前的身份认证:从在meta.sr.ht注册 OAuth 客户端、配置回跳地址,到针对自建 SourceHut 实例覆盖四个关键端点,再到结合源码剖析会话补全(GraphQL 拉取邮箱与用户名)与令牌校验的实现细节,并给出基于邮箱的访问控制方案。读完本文,你将能独立把 oauth2-proxy 与 SourceHut 官方或自建实例对接起来并验证其行为。
一、SourceHut 提供方的工作原理
oauth2-proxy 将 SourceHut 作为内置的 Provider 之一。在源码层面,它由 providers/srht.go 中的SourceHutProvider实现,该结构体内嵌了通用ProviderData,并声明实现了Provider接口(providers/srht.go)。
从源码可以看到该提供方默认指向 SourceHut 官方元服务meta.sr.ht,预置了四个端点与一个只读权限范围(providers/srht.go):
| 端点 | 默认值 | 用途 |
|---|---|---|
| Login URL(授权) | https://meta.sr.ht/oauth2/authorize | 发起 OAuth 授权请求 |
| Redeem URL(换 token) | https://meta.sr.ht/oauth2/access-token | 用授权码换取访问令牌 |
| Profile URL(用户信息) | https://meta.sr.ht/query | GraphQL 端点,用于获取用户资料 |
| Validate URL(令牌校验) | https://meta.sr.ht/profile | 校验访问令牌是否有效 |
| 默认 Scope | meta.sr.ht/PROFILE:RO | 只读读取用户档案权限 |
当用户以--provider=sourcehut启动时,providers/providers.go 会命中options.SourceHutProvider分支并调用NewSourceHutProvider完成上述默认值的注入。另外需要注意,providerRequiresOIDCProviderVerifier对 SourceHut 返回false(providers/providers.go),说明该提供方走的是「令牌校验 + 用户信息补全」的经典 OAuth 2.0 流程,而非依赖 OIDC Discovery 的自动发现机制——这也正是自建实例时必须手动指定四个端点的原因。
二、前置准备:注册 OAuth 客户端
无论使用官方meta.sr.ht还是自建实例,第一步都是在 SourceHut 侧创建一个 OAuth 客户端:
- 打开
https://meta.sr.ht/oauth2(自建实例则为https://<meta.your.instance>/oauth2),新建一个 OAuth client; - 在Redirection URI(回跳地址)一栏填写 oauth2-proxy 的认证回调地址,格式必须是
https://internal.yourcompany.com/oauth2/callback
其中https://internal.yourcompany.com是 oauth2-proxy 对外服务的实际域名,/oauth2/callback是固定的回调路径。注册完成后,记下该客户端生成的 Client ID 与 Client Secret,它们将作为--client-id与--client-secret传入 oauth2-proxy。
三、基础配置:接入官方 SourceHut
使用官方 SourceHut 元服务时,不需要配置任何端点,只需在启动命令中声明 provider 类型与客户端凭据:
./oauth2-proxy \ --provider=sourcehut \ --client-id="<your-client-id>" \ --client-secret="<your-client-secret>" \ --email-domain="yourcompany.com" \ --http-address="0.0.0.0:4180" \ --upstream="http://127.0.0.1:8080" \ --cookie-secret="<a-secure-random-secret>"除--provider=sourcehut外,其余为 oauth2-proxy 的通用参数:--email-domain限定允许认证的邮箱域(详见下文「访问控制」),--upstream指向被保护的后端服务,--cookie-secret用于加密会话 Cookie。
四、接入自建 SourceHut 实例
如果团队自行部署了 SourceHut,则需要显式覆盖以下四个端点,让 oauth2-proxy 指向自己的实例(官方配置说明):
./oauth2-proxy \ --provider=sourcehut \ --client-id="<your-client-id>" \ --client-secret="<your-client-secret>" \ --login-url="https://<meta.your.instance>/oauth2/authorize" \ --redeem-url="https://<meta.your.instance>/oauth2/access-token" \ --profile-url="https://<meta.your.instance>/query" \ --validate-url="https://<meta.your.instance>/profile"这四个参数在 pkg/apis/options/legacy_options.go 中定义,对应的命令行标志与配置文件字段映射如下:
| 命令行标志 | 配置文件字段(cfg) | 含义 |
|---|---|---|
--login-url | login_url | 认证端点(Authorization Endpoint) |
--redeem-url | redeem_url | 令牌兑换端点(Token Endpoint) |
--profile-url | profile_url | 资料访问端点(UserInfo/GraphQL Endpoint) |
--validate-url | validate_url | 访问令牌校验端点 |
这些 URL 最终会在newProviderDataFromConfig中被逐个解析进ProviderData(providers/providers.go);若任一 URL 无法解析,oauth2-proxy 会聚合返回错误并拒绝启动,因此自建实例的地址必须书写为合法且可访问的 URL。
五、会话补全与令牌校验的源码级实现
在 OAuth 授权码流程完成、拿到 access token 之后,SourceHutProvider 还需要把用户信息写入会话,并周期性校验令牌是否仍然有效。这两件事分别由EnrichSession与ValidateSession完成(providers/srht.go)。
5.1 通过 GraphQL 补全邮箱与用户名
EnrichSession向后端ProfileURL(即/query端点)发送一个POST请求,请求体是 GraphQL 查询{"query": "{ me { username, email } }"},并在Authorization: Bearer <access_token>头中携带访问令牌。返回的 JSON 形如:
{ "data": { "me": { "username": "bitfehler", "email": "ch@bitfehler.net" } } }随后实现分别从data.me.email与data.me.username中取值,写入会话的Email、PreferredUsername与User字段(providers/srht.go)。也就是说,oauth2-proxy 用于展示登录用户名、参与邮箱过滤的字段,正是通过这一次 GraphQL 请求从 SourceHut 拉取的。
5.2 令牌校验的两种判定
ValidateSession调用通用的validateToken,并构造一个带Accept: application/json的 OIDC 风格请求头(providers/srht.go、providers/util.go),最终访问ValidateURL(即/profile端点)来确认 access token 是否有效。该行为在 providers/srht_test.go 中有对应测试覆盖:
- 当后端对
/query与/profile均返回正确响应时(模拟用户bitfehler),ValidateSession返回true; - 当后端不返回任何
/query、/profile响应(404)时,ValidateSession返回false。
如果你在排查「登录成功后很快又失效」「用户信息为空」等问题,可以优先检查这两个端点的可达性与返回格式是否与上述测试中的样例一致。
六、访问控制:目前仅支持基于邮箱的授权
文档明确指出:默认配置下,任何拥有 SourceHut 账户的用户都能通过认证。若要限制访问范围,目前 SourceHut 提供方仅支持基于邮箱的授权方式,不支持基于组(group)的过滤,相关说明见 Providers 索引文档。
三种邮箱授权写法如下:
# 1. 授权某个邮箱域下的所有用户 --email-domain=yourcompany.com # 2. 授权指定邮箱白名单(文件每行一个邮箱地址) --authenticated-emails-file=/path/to/allowed-emails.txt # 3. 放开所有邮箱域(慎用,相当于所有账户可登录) --email-domain=*由于 SourceHut 提供方的邮箱来自/query端点返回的me.email字段,因此上述过滤在自建实例下同样生效——只要自建实例正确返回了邮箱信息。
七、快速验证与排障建议
- 确认回调地址一致:
meta.sr.ht/oauth2中填写的 Redirection URI 必须与 oauth2-proxy 实际暴露的https://<你的域名>/oauth2/callback完全一致(含协议与端口)。 - 确认默认端点是否适用:仅在使用官方
meta.sr.ht时才能省略四个 URL 参数;自建实例必须全部显式指定,否则会跳转到官方地址导致认证失败。 - 验证用户信息拉取:用 access token 手动请求
POST https://<meta.your.instance>/query,请求体为{"query": "{ me { username, email } }"},确认能返回邮箱与用户名。 - 观察日志与测试:参考 providers/srht_test.go 中 mock 后端的响应格式,可帮助判断是 oauth2-proxy 配置问题还是 SourceHut 实例返回不符合预期。
结语
SourceHut 是 oauth2-proxy 内置提供方中比较「轻量」的一个:它不依赖 OIDC Discovery,而是通过/authorize、/access-token、/query、/profile四个固定端点完成授权、换令牌、拉资料与校验四步闭环。无论是直连官方meta.sr.ht还是接入自建实例,核心都在于正确填写四个端点地址与回调 URL;而访问控制方面,请记住当前版本的 SourceHut 提供方只支持邮箱维度的授权(--email-domain/--authenticated-emails-file)。结合本文给出的源码路径与测试用例,你可以快速定位并解决集成过程中遇到的大多数问题。
【免费下载链接】oauth2-proxyA reverse proxy that provides authentication with Google, Azure, OpenID Connect and many more identity providers.项目地址: https://gitcode.com/GitHub_Trending/oa/oauth2-proxy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考