使用 oauth2-proxy 对接 Gitea:基于 GitHub Provider 的 OAuth2 登录配置完整指南
【免费下载链接】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
本文以 oauth2-proxy 官方文档中 Gitea 配置指南 为核心,讲解如何让 oauth2-proxy 通过 Gitea 完成第三方登录。核心要点在于:Gitea 并非一个独立的 Provider 实现,而是直接复用 GitHub Provider 的协议流程,只需把登录、换 token、校验三个端点指向自建 Gitea 实例即可。读完本文,你将掌握从 Gitea 创建 OAuth2 应用、到编写 oauth2-proxy 命令行参数或配置文件、再到按组织/团队/仓库进行细粒度访问控制的完整实战方案。
Gitea 不是独立 Provider:先理解其架构定位
oauth2-proxy 支持多种身份提供方(Google、Azure、OpenID Connect、GitHub 等),但官方文档明确说明:Gitea 并没有自己专属的 Provider,其 OAuth2 流程与 GitHub 高度兼容,因此直接复用 GitHub Provider,并通过--login-url、--redeem-url、--validate-url三个参数把请求端点指向你的 Gitea 服务器。
这一点在源码中得到印证:测试文件 providers/gitea_test.go 中构造的testGiteaProvider函数,实际返回的类型就是*GitHubProvider,其中ProviderName被显式设置为"Gitea",ValidateURL路径指向/api/v1/user/emails——这正是 Gitea 的 API 风格(GitHub 的校验路径是/api/v3)。也就是说,同一套 GitHub 协议实现,通过端点地址的替换即可服务 Gitea。
第一步:在 Gitea 中创建 OAuth2 应用
登录你的 Gitea 实例,进入个人设置中的应用管理页面:
https://<your gitea host>/user/settings/applications点击创建新应用(New Application),在
Redirect URI一栏填写 oauth2-proxy 的回调地址,格式为:https://<proxied host>/oauth2/callback注意:
<proxied host>是最终被 oauth2-proxy 反向代理保护的服务对外域名,/oauth2/callback是 oauth2-proxy 默认的回调路径(由--redirect-url决定,两者必须完全一致)。创建成功后,Gitea 会生成一对Client ID和Client Secret,将其记录下来,后续配置 oauth2-proxy 时需要用到。
第二步:传递 Provider 参数给 oauth2-proxy
官方文档给出的命令行配置如下:
--provider="github" --redirect-url="https://<proxied host>/oauth2/callback" --provider-display-name="Gitea" --client-id="< client_id as generated by Gitea >" --client-secret="< client_secret as generated by Gitea >" --login-url="https://< your gitea host >/login/oauth/authorize" --redeem-url="https://< your gitea host >/login/oauth/access_token" --validate-url="https://< your gitea host >/api/v1/user/emails"各参数作用如下:
| 参数 | 作用 |
|---|---|
--provider="github" | 指定复用 GitHub Provider 的协议实现(Gitea 没有独立 provider 名) |
--redirect-url | 回调地址,必须与 Gitea 应用中填写的 Redirect URI 一致 |
--provider-display-name="Gitea" | 登录页面上显示的提供方名称,让用户看到的是 "Gitea" 而非 "GitHub" |
--client-id/--client-secret | Gitea 应用生成的应用凭据 |
--login-url | 授权端点,将用户引导至 Gitea 的 OAuth2 授权页 |
--redeem-url | 令牌交换端点,用授权码换取 access token |
--validate-url | 会话校验端点,用于验证 token 并获取邮箱信息 |
第三步:使用配置文件的方式(推荐)
oauth2-proxy 同时支持命令行参数与配置文件两种方式,配置项一一对应(蛇形命名)。仓库自带的本地示例 contrib/local-environment/oauth2-proxy-gitea.cfg 给出了完整可运行的配置:
http_address="0.0.0.0:4180" cookie_secret="OQINaROshtE9TcZkNAm-5Zs2Pv3xaWytBmc5W7sPX7w=" email_domains=["localhost"] cookie_secure="false" upstreams="http://httpbin" cookie_domains=[".localtest.me"] # Required so cookie can be read on all subdomains. whitelist_domains=[".localtest.me"] # Required to allow redirection back to original requested target. client_id="ef0c2b91-2e38-4fa8-908d-067a35dbb71c" client_secret="gto_qdppomn2p26su5x46tyixj7bcny5m5er2s67xhrponq2qtp66f3a" redirect_url="http://oauth2-proxy.localtest.me:4180/oauth2/callback" # gitea provider provider="github" provider_display_name="Gitea" login_url="http://gitea.localtest.me:3000/login/oauth/authorize" redeem_url="http://gitea.localtest.me:3000/login/oauth/access_token" validate_url="http://gitea.localtest.me:3000/api/v1/user/emails"配置说明:
provider="github"与provider_display_name="Gitea"配合,让底层走 GitHub 协议、界面显示 Gitea;login_url/redeem_url/validate_url三个地址都指向 Gitea 服务(示例中为gitea.localtest.me:3000);email_domains声明允许的邮箱域名,用于基本的邮箱域过滤;- 本地测试时需将
cookie_secure设为false,生产环境必须启用 HTTPS 并保持true; - 该文件配合 contrib/local-environment/docker-compose-gitea.yaml 使用,一条命令即可拉起完整的 oauth2-proxy + Gitea + HTTPBin 测试环境。
源码级原理:GitHub Provider 如何兼容 Gitea
从源码看,兼容性并非巧合,而是 GitHub Provider 实现中针对 Gitea 做了显式支持。核心实现在 providers/github.go:
- 默认端点(providers/github.go#L40-L65):Provider 内置了 GitHub 的默认授权、换 token、API 校验地址;对接 Gitea 时,这些默认值全部被
--login-url、--redeem-url、--validate-url覆盖为 Gitea 的地址。 - API 基础路径自适应(providers/github.go#L94-L113):
makeGitHubAPIEndpoint会从ValidateURL.Path中正则匹配/api/v\d+段作为 API 基础路径。因此validate_url既可以填https://gitea.example.com/api/v1/user/emails,也能填 GitHub Enterprise 风格的https://host/api/v3,后续的/user、/user/orgs、/user/teams、/user/emails、/repos/...等请求都会自动拼接在这个基础路径之下。 - 组织/团队字段双兼容(providers/github.go#L462-L512):
getOrgs解析的组织 JSON 结构同时支持 GitHub 的login字段与 Gitea 的name字段,日志分别输出 "Member of Github Organization" 与 "Member of Gitea Organization";getTeams同样兼容两者(providers/github.go#L514-L568)。 - 邮箱验证:
getEmail调用/user/emails端点,选取verified且primary的邮箱写入会话状态(providers/github.go#L337-L367),这正对应 Gitea 的validate_url指向/api/v1/user/emails的原因。
会话校验逻辑在 providers/gitea_test.go 中有对应的单元测试:
TestGiteaProvider_ValidateSessionWithBaseUrl:模拟 Gitea 后端不返回任何邮箱数据时,ValidateSession返回false(校验失败);TestGiteaProvider_ValidateSessionWithUserEmails:模拟 Gitea 返回[{"email": "...", "verified": true, "primary": true}]时,校验通过。
这两条测试清晰地展示了"用 Gitea 的 /api/v1/user/emails 响应验证会话有效性"这一核心链路。
进阶:按组织、团队、仓库与用户限制访问
由于底层是 GitHub Provider,GitHub Provider 配置选项 中全部访问控制能力对 Gitea 同样生效:
| Flag | Toml Field | 类型 | 说明 |
|---|---|---|---|
--github-org | github_org | string | 仅允许指定组织的成员登录 |
--github-team | github_team | string | 仅允许指定团队(slug)或(org:team)的成员登录,逗号分隔 |
--github-repo | github_repo | string | 仅允许某仓库的协作者登录,格式orgname/repo |
--github-token | github_token | string | 用于校验仓库协作者的 token(需对该仓库有 push 权限) |
--github-user | github_users | string | list | 按用户名放行,即使不属于上述 org/team/协作者范围也可登录 |
典型用法示例:
# 仅允许组织成员 --github-org="your-org" # 仅允许组织内指定团队(slug),逗号分隔 --github-org="your-org" --github-team="team1,team2,team3" # 跨组织限制团队时,org 置空、团队使用 org:slug 全限定名 --github-org="" --github-team="org1:team1,org2:team1,org3:team42,octo:cat" # 限制为仓库协作者(公共仓库需 push 权限,私有仓库任意访问权限即可) --github-repo="your-org/your-repo" # 按用户名放行 --github-user="alice,bob"实现层面(providers/github.go#L407-L433):
checkRestrictions根据Org/Team的组合调用hasOrg、hasOrgAndTeam或hasTeam进行分组校验;- 组织与团队信息在
EnrichSession阶段通过/user/orgs与/user/teams拉取,并写入会话的Groups字段,最终以X-Forwarded-Groups请求头转发给上游服务,格式形如org1:team1,org1:team2,org2:team1; - 仓库协作者校验通过
/repos/{repo}与/repos/{repo}/collaborators/{username}完成:公共仓库要求用户有 push 权限,私有仓库要求有 pull 权限(providers/github.go#L255-L288); --github-user配置的用户会被优先放行,跳过后续所有限制(checkUserRestriction,providers/github.go#L435-L451);- 注意:Gitea 的团队校验基于组织中的
name字段(而 GitHub 使用 slug),团队配置请以 Gitea 组织中的实际团队名为准。
本地快速验证:一键拉起 Gitea 测试环境
仓库在 contrib/local-environment 提供了开箱即用的本地联调环境,通过 docker-compose-gitea.yaml 同时启动三个容器:
- oauth2-proxy:加载上面提到的 oauth2-proxy-gitea.cfg 配置;
- gitea/gitea:充当身份提供方,映射端口 3000;
- httpbin:作为被保护的上游示例服务。
启动方式(在contrib/local-environment目录下):
docker compose -f docker-compose-gitea.yaml up -d环境就绪后:
- 访问
http://oauth2-proxy.localtest.me:4180触发完整登录流程,默认测试账号为admin@example.com,密码password; - 访问
http://gitea.localtest.me:3000可用同一账号登录 Gitea 后台,查看应用与授权设置; - 该 Makefile 还提供了便捷指令
make gitea-up、make gitea-down等(见 contrib/local-environment/Makefile)。
小结与注意事项
- 没有 Gitea provider,只有 GitHub provider:对接 Gitea 的全部奥义就是
--provider="github"加上指向 Gitea 的三个端点 URL; redirect-url必须与 Gitea 应用内填写的 Redirect URI逐字符一致;- 生产环境务必启用 HTTPS,并将
cookie_secure设为true;如需跨子域共享 Cookie,可参考示例配置中的cookie_domains与whitelist_domains; - 访问控制能力(组织/团队/仓库/用户)与 GitHub Provider 完全通用,可结合
--email-domain做邮箱域过滤,多层限制可叠加使用; - 想从零复现本文流程,直接使用
contrib/local-environment中的 compose 环境即可,无需自行部署 Gitea。
【免费下载链接】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),仅供参考