最近自建服务越搭越多,Wiki、博客、Mailcow、面板各有一套登录。部分应用支持 Google,部分只认标准 OIDC,还有些应用虽然支持 OIDC,但账号字段又对不上。
为了解决这个问题,我写了一个轻量的自托管 SSO 中间件:AuthRouter。
GitHub:https://github.com/YIYI-16/AuthRouter
Docker 镜像:ghcr.io/yiyi-16/authrouter:latest
项目使用 MIT License,欢迎试用、提 Issue 或 PR。如果这个项目刚好解决了你的问题,也欢迎点一个 Star 支持一下。
它是做什么的?
简单来说,它位于“登录账号”和“自建应用”之间:
Google / GitHub / Keycloak / Azure AD / Authentik ...
|
OIDC / OAuth2
v
AuthRouter
|
标准 OpenID Connect
v
Mailcow / Wiki / Blog / 自建服务 ...
面向上游时,它是一个 OIDC / OAuth2 Client;面向下游时,它是一个标准 OIDC Provider。
这样一来,下游应用只需要对接一次 AuthRouter,之后增加或更换 Google、GitHub、Keycloak 等上游登录方式,不需要逐个修改所有下游应用。
目前支持的功能
- 多个标准 OIDC 上游,通过 Issuer 自动发现端点
- 通用 OAuth2 上游,可手动配置授权、令牌、用户信息及邮箱接口
- Web 管理面板,无需改配置文件即可管理上游 IdP、下游客户端和身份映射
- 配置修改后即时生效,无需重启容器
- 为每个下游应用独立生成 Client ID 和 Client Secret
- 支持
client_secret_post与client_secret_basic - 支持 SQLite 和 MySQL,个人部署不需要额外准备数据库
- 自动生成并持久化 JWKS、加密密钥和 Session 签名密钥
- 只有一个上游时自动跳转;有多个上游时显示登录方式选择页
- 提供标准 Discovery、Authorization、Token、UserInfo 和 JWKS 端点
- 提供
/health健康检查接口
一个比较实用的功能:按应用映射身份
除了单纯透传账号,AuthRouter 还可以针对不同下游应用映射不同身份。
例如我使用 [email protected] 登录:
- 进入 Mailcow 时映射为
[email protected] - 进入 Wiki 时继续使用原始 Gmail 邮箱
- 同一个来源账号配置了多个目标身份时,登录过程中会显示账号选择页
映射规则按“下游客户端 + 上游登录源 + 上游身份”生效,不会影响其他应用。没有配置映射时,则直接透传上游身份。
Docker 快速部署
需要准备一个域名和 HTTPS 反向代理。公网 OIDC 登录依赖正确的 Issuer 和安全 Cookie,因此不建议直接用 IP + HTTP 部署。
docker run -d \
--name authrouter \
--restart unless-stopped \
-p 127.0.0.1:3000:3000 \
-e SSO_BASE_URL=https://sso.example.com \
-e ADMIN_PASSWORD='请替换为足够长的随机密码' \
-v sso-data:/app/data \
ghcr.io/yiyi-16/sso:latest
镜像由 GitHub Actions 构建并发布到 GHCR,目前同时支持 linux/amd64 和 linux/arm64。
也可以从源码使用 Docker Compose 部署:
git clone https://github.com/YiYi-16/AuthRouter.git
cd AuthRouter
cp .env.example .env
# 编辑 .env,至少设置 SSO_BASE_URL 和 ADMIN_PASSWORD
docker compose up -d --build
Nginx 反向代理的核心配置如下,仓库里也提供了完整的 nginx.conf 示例:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
}
启动后可以先检查:
curl https://sso.example.com/health
curl https://sso.example.com/.well-known/openid-configuration
然后访问 https://sso.example.com/admin:
- 添加一个上游 OIDC 或 OAuth2 登录源。
- 在上游平台登记回调地址:
https://sso.example.com/sso/{provider_id}/callback。 - 创建下游 OIDC 客户端并保存只显示一次的 Client Secret。
- 将 Discovery URL、Client ID 和 Client Secret 填入下游应用。
- 从下游应用发起一次完整登录测试。
下游应用支持自动发现时,只需使用:
https://sso.example.com/.well-known/openid-configuration
手动配置时,对应端点为:
| 配置项 | 地址 |
|---|---|
| Issuer | https://sso.example.com |
| Authorization Endpoint | https://sso.example.com/auth |
| Token Endpoint | https://sso.example.com/token |
| UserInfo Endpoint | https://sso.example.com/me |
| JWKS URI | https://sso.example.com/jwks |
| Scopes | openid email profile |
SQLite 与 MySQL
默认使用 SQLite,数据库保存在 /app/data/sso.db,适合个人和单机部署。
如果已有 MySQL,也可以通过环境变量切换:
DB_DRIVER=mysql
MYSQL_HOST=mysql.example.internal
MYSQL_PORT=3306
MYSQL_USER=sso
MYSQL_PASSWORD=replace-with-a-database-password
MYSQL_DATABASE=sso
应用会自动创建业务表,但需要提前创建好 MySQL Database 和账号。无论使用哪种数据库,都要持久化并备份 /app/data,因为 JWKS、加密密钥和 Session 密钥也保存在这里。
当前版本尚未支持的能力
项目目前主要围绕个人、小团队和可信网络边界内的自托管场景开发,仍处于持续完善阶段。当前版本需要注意:
- 目前仅建议单实例部署,管理员 Session 和部分授权临时状态仍保存在进程内存中,多副本状态共享暂未实现
- 服务重启时,正在进行的授权流程暂时无法继续,需要从下游应用重新发起登录
- 管理面板 MFA、细粒度权限和审计日志暂未实现
- TLS 终止暂未集成,需要配合 Nginx、Caddy 或 Traefik
- 自动备份和密钥轮换暂未实现,目前需要自行备份数据库与
/app/data
这些只是当前版本的能力边界,未来均保留继续完善的可能。后续会结合实际使用反馈、实现复杂度和大家的需求来确定开发优先级。如果现阶段就需要多副本高可用、完整审计或复杂组织架构,可以先评估 Keycloak、Authentik 等成熟方案;AuthRouter 当前更适合“用一个容器解决个人服务统一登录和身份转换”的场景。
想听听大家的意见
项目还在持续完善中,目前的功能更多来自我自己的使用场景,也很希望听听大家在实际自建服务中的需求。无论是功能建议、架构思路、交互改进,还是兼容性问题,都欢迎在帖子下讨论或到 GitHub 提 Issue。
如果你手上有比较特殊的上游 IdP 或下游应用,反馈时可以带上这些信息:
- 使用的上游登录源
- 需要接入的下游应用
- SQLite 或 MySQL
- 具体报错和可复现步骤
仓库地址:https://github.com/YIYI-16/AuthRouter
特别想征集大家对这些方向的看法:多实例与高可用、管理面板 MFA、审计日志、更多数据库支持、配置导入导出,以及常见自建应用的接入文档。也欢迎提出我没有想到的使用场景,为后续迭代提供一些思路。
如果你觉得项目有用,欢迎到 GitHub 点个 Star。Star 和实际反馈都能帮助我判断哪些能力更值得优先完善,感谢大家。
不明觉厉
通过上游统一管理下游登录方式?
@book思议 #2
假如说之前需要同时接入Google和Github等多个登录 那就需要去设置至少两个OAuth端点 但是如果用这个项目的话只用设置一个端点就可以同时接入多个登录了 登录信息也是完全一致的
感觉有点像tinyauth?是类似的东西吗
@fnnnpp #4
不是的 这个是可以接入tinyauth的 让tinyauth作为上游
这个项目不是用来自己做身份认证的 是将多种不一样的身份认证进行整合 再提供统一的OIDC接口
相当于是一个代理或者中继器
@YiYi8512 #5 学习了,持续关注下,感觉确实是个需求
AuthRouter 最近完成了一次比较大的 2.x 更新,核心目标是提高稳定性、协议兼容性和部署体验。之前关注或部署过的朋友可以看一下,主要变化如下:
登录和协议兼容性
state和nonce,避免回调串线。/.well-known/openid-configuration、Token、UserInfo 和 JWKS 端点经过完整烟雾测试。稳定性和数据安全
部署方式调整
linux/amd64和linux/arm64。AUTHROUTER_IMAGE固定版本,升级和回滚都只需要修改.env后重新拉取。新部署可以在
.env中设置:然后执行:
已有部署升级前请先备份
sso-dataVolume。现有 SQLite / MySQL 表结构、环境变量、OIDC 端点和管理配置保持兼容;升级或重启时,正在进行中的登录流程需要从下游应用重新发起。这次还补充了自动化测试,目前覆盖输入校验、Session、CSRF、OAuth2 兼容性、OIDC Discovery 和管理后台登录流程。
项目新地址:https://github.com/YIYI-16/AuthRouter
镜像地址:
ghcr.io/yiyi-16/authrouter:latest部署文档已经重新整理成面向用户的服务器部署、升级和回滚指南。欢迎大家继续反馈特殊上游 IdP、下游应用兼容性和实际部署中遇到的问题。