一个将 QQ 互联 OAuth2 登录转换为标准 OIDC (OpenID Connect) 协议的适配器服务,用于与 Keycloak 等 OIDC 兼容的身份认证系统集成。
本项目作为中间件,桥接了 QQ 互联的 OAuth2.0 认证流程与标准 OIDC 协议,使得 Keycloak 等身份提供商能够通过标准 OIDC 流程接入 QQ 登录。
- OAuth2 到 OIDC 转换: 将 QQ 互联的 OAuth2 响应转换为标准 OIDC Claims
- 授权码流程: 完整实现 OIDC 授权码模式 (Authorization Code Flow)
- 状态管理: 使用内存存储管理 Keycloak 状态和授权码
- JWT Token 生成: 生成符合 OIDC 标准的 ID Token
- 用户信息映射: 将 QQ 用户信息映射到标准 OIDC 用户属性
- Spring Boot: Web 框架
- Spring Web: RESTful API 支持
- JWT: ID Token 生成
- RestTemplate: HTTP 客户端调用
Keycloak → /auth → QQ OAuth → /callback/qq → /token → Keycloak
- 接收来自 Keycloak 的认证请求
- 生成内部状态码并存储 Keycloak 回调信息
- 重定向用户到 QQ 登录页面
- 接收 QQ 授权码
- 使用授权码获取 access_token 和 openid
- 获取 QQ 用户信息
- 生成 OIDC 授权码并存储用户声明
- 重定向回 Keycloak
- 验证授权码
- 生成符合 OIDC 标准的 ID Token (JWT)
- 返回 Token 响应
docker run -d \
--name qq2oidc \
-p 8080:8080 \
-e QQ_APP_ID=your_qq_app_id \
-e QQ_SECRET_KEY=your_qq_secret_key \
-e ADAPTER_JWT_SECRET=your_jwt_secret \
-e ADAPTER_ISSUER_URI=https://your-domain.com \
-e ADAPTER_CALLBACK_URI=https://your-domain.com/callback/qq \
registry.dforwa.cn:2053/gitlab/qq2oidc:latest创建 docker-compose.yml 文件:
version: '3.8'
services:
qq2oidc:
image: registry.dforwa.cn:2053/gitlab/qq2oidc:latest
container_name: qq2oidc
ports:
- "8080:8080"
environment:
# QQ 互联配置
- QQ_APP_ID=${QQ_APP_ID}
- QQ_SECRET_KEY=${QQ_SECRET_KEY}
# 适配器配置
- ADAPTER_JWT_SECRET=${ADAPTER_JWT_SECRET}
- ADAPTER_ISSUER_URI=${ADAPTER_ISSUER_URI}
- ADAPTER_CALLBACK_URI=${ADAPTER_CALLBACK_URI}
restart: unless-stopped
创建 .env 文件配置环境变量:
# QQ 互联配置
QQ_APP_ID=your_qq_app_id
QQ_SECRET_KEY=your_qq_secret_key
# 适配器配置
ADAPTER_JWT_SECRET=FRkCN...kgTcTn
ADAPTER_ISSUER_URI=https://your-domain.com
ADAPTER_CALLBACK_URI=https://your-domain.com/callback/qq启动服务:
docker-compose up -d# QQ 互联配置
qq:
app-id: QQ互联的APPID
app-key: QQ互联的APPKEY
server:
port: 8080(服务器监听端口)
# 适配器配置
adapter:
issuer-uri: http://your-domain.com/ (设置中间件地址)
callback-uri: http://your-domain.com/callback/qq (设置回调地址)
jwt-secret: 你的jwt密钥(需要大于32字符)| 端点 | 方法 | 说明 |
|---|---|---|
/auth |
GET | 接收 Keycloak 认证请求,发起 QQ 登录 |
/callback/qq |
GET | QQ 登录回调端点 |
/token |
POST | OIDC Token 端点,返回 ID Token |
state: Keycloak 状态码redirect_uri: Keycloak 回调地址nonce: 防重放随机数
code: QQ 授权码state: 内部状态码
code: OIDC 授权码grant_type: 授权类型 (authorization_code)client_id: 客户端 IDclient_secret: 客户端密钥redirect_uri: 重定向 URI
| QQ 字段 | OIDC Claim | 说明 |
|---|---|---|
| openid | sub | 用户唯一标识 |
| nickname | name | 用户昵称 |
| figureurl_qq_2 | picture | 用户头像 URL |
| gender | gender | 性别 |
| - | 伪造邮箱 ([email protected]) | |
| - | email_verified | 固定为 false |
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>- 实现
.well-known/openid-configuration端点 - 使用 Redis 替代内存存储会话数据
- 添加授权码过期机制
- 完善错误处理和日志记录
- 添加 HTTPS 强制要求
- 实现 Token 刷新机制
- 当前使用内存存储,重启后会话数据丢失
- 生产环境建议使用 Redis 等持久化存储
- 确保所有通信使用 HTTPS
- 妥善保管 QQ App Key 和客户端密钥
- 授权码应设置合理的过期时间
- HTTPS 配置: 生产环境必须启用 HTTPS
- 会话存储: 集群部署时使用 Redis 共享会话
- 日志监控: 配置完善的日志和监控系统
- 限流保护: 添加接口访问频率限制
- 创建自定义 Identity Provider
- 配置 Authorization URL:
http://your-domain.com/auth - 配置 Token URL:
http://your-domain.com/token - 设置所需的 Client ID 和 Client Secret
- 配置 Scopes:
openid profile
根据项目实际情况添加许可证信息
欢迎提交 Issue 和 Pull Request
- 项目地址:
pw.es8.qq2oidc
注意: 本项目仅供学习和参考使用,生产环境使用前请完善安全机制和错误处理。