@builder6/oidc-provider
v3.2.12
Published
Builder6 OIDC Provider 模块为 Builder6 平台提供 OpenID Connect (OIDC) 身份提供者(Identity Provider, IdP)功能,允许 Builder6 作为认证服务器为其他应用提供单点登录(SSO)服务。
Keywords
Readme
Builder6 OIDC Provider Module
Builder6 OIDC Provider 模块为 Builder6 平台提供 OpenID Connect (OIDC) 身份提供者(Identity Provider, IdP)功能,允许 Builder6 作为认证服务器为其他应用提供单点登录(SSO)服务。
功能特性
- OIDC 标准支持: 完全符合 OpenID Connect 1.0 规范
- 多租户支持: 支持多租户 OIDC 配置
- 授权码流程: 支持 Authorization Code Flow
- 隐式流程: 支持 Implicit Flow
- 混合流程: 支持 Hybrid Flow
- 客户端凭据流: 支持 Client Credentials Flow
- 刷新令牌: 支持 Refresh Token
- 用户信息端点: 提供标准的 UserInfo 端点
- Discovery 端点: 自动发现配置端点
- JWT 令牌: 使用 JWT 格式的 ID Token 和 Access Token
- 密码加密: 使用 bcrypt 加密客户端密钥
安装
npm install @builder6/oidc-provider或
yarn add @builder6/oidc-provider环境变量
基本配置
# OIDC 客户端 ID
B6_OIDC_PROVIDER_CLIENT_ID=your-client-id
# OIDC 客户端密钥
B6_OIDC_PROVIDER_CLIENT_SECRET=your-secret
# 允许的重定向 URI(逗号分隔)
B6_OIDC_PROVIDER_REDIRECT_URIS=http://localhost:5100/callback,https://app.example.com/callback高级配置
# Token 过期时间(秒)
B6_OIDC_PROVIDER_ACCESS_TOKEN_TTL=3600
B6_OIDC_PROVIDER_ID_TOKEN_TTL=3600
B6_OIDC_PROVIDER_REFRESH_TOKEN_TTL=86400
# 支持的授权类型(空格分隔)
B6_OIDC_PROVIDER_GRANT_TYPES=authorization_code refresh_token
# 支持的响应类型(空格分隔)
B6_OIDC_PROVIDER_RESPONSE_TYPES=code id_token token
# 支持的作用域(空格分隔)
B6_OIDC_PROVIDER_SCOPES=openid profile email phone address
# Issuer URL(通常自动设置)
B6_OIDC_PROVIDER_ISSUER=https://your-domain.com
# 签名算法
B6_OIDC_PROVIDER_ID_TOKEN_SIGNING_ALG=RS256多客户端配置
可以通过数据库配置多个 OIDC 客户端,每个客户端有独立的配置。
使用示例
在 NestJS 应用中集成
import { Module } from '@nestjs/common';
import { OidcProviderModule } from '@builder6/oidc-provider';
@Module({
imports: [OidcProviderModule],
})
export class AppModule {}配置 OIDC 客户端
import { OidcProviderService } from '@builder6/oidc-provider';
constructor(private oidcProviderService: OidcProviderService) {}
async registerClient() {
const client = await this.oidcProviderService.registerClient({
client_id: 'my-app',
client_secret: 'secret-key',
redirect_uris: [
'https://my-app.com/callback',
'https://my-app.com/silent-renew'
],
grant_types: ['authorization_code', 'refresh_token'],
response_types: ['code'],
token_endpoint_auth_method: 'client_secret_post',
application_type: 'web'
});
return client;
}OpenID Configuration URI
OIDC Discovery 端点提供服务器的配置信息:
http://localhost:5100/api/v6/idp/common/.well-known/openid-configuration该端点返回的配置包括:
{
"issuer": "http://localhost:5100/api/v6/idp/common",
"authorization_endpoint": "http://localhost:5100/api/v6/idp/common/auth",
"token_endpoint": "http://localhost:5100/api/v6/idp/common/token",
"userinfo_endpoint": "http://localhost:5100/api/v6/idp/common/userinfo",
"jwks_uri": "http://localhost:5100/api/v6/idp/common/jwks",
"scopes_supported": ["openid", "profile", "email"],
"response_types_supported": ["code", "id_token", "token"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"id_token_signing_alg_values_supported": ["RS256"]
}OIDC 端点
认证端点
GET/POST /api/v6/idp/common/auth
发起 OIDC 认证流程。
参数:
client_id: 客户端 IDredirect_uri: 重定向 URIresponse_type: 响应类型(code, id_token, token)scope: 作用域(openid 必需)state: 状态参数(推荐)nonce: Nonce 值(使用 id_token 时必需)
令牌端点
POST /api/v6/idp/common/token
交换授权码或刷新令牌。
参数:
grant_type: authorization_code 或 refresh_tokencode: 授权码(grant_type=authorization_code)refresh_token: 刷新令牌(grant_type=refresh_token)client_id: 客户端 IDclient_secret: 客户端密钥redirect_uri: 重定向 URI
用户信息端点
GET /api/v6/idp/common/userinfo
获取认证用户的信息。
需要在 Authorization 头中提供有效的访问令牌:
Authorization: Bearer ACCESS_TOKENJWKS 端点
GET /api/v6/idp/common/jwks
获取用于验证 JWT 令牌的公钥集。
授权流程示例
授权码流程(Authorization Code Flow)
这是最常用的授权流程,适用于服务器端应用。
1. 重定向到认证端点
GET http://localhost:5100/api/v6/idp/common/auth?
response_type=code&
client_id=your-client-id&
redirect_uri=https://your-app.com/callback&
scope=openid profile email&
state=random-state2. 用户登录并授权
用户在 Builder6 登录页面登录并授权应用访问其信息。
3. 重定向回应用
https://your-app.com/callback?
code=AUTHORIZATION_CODE&
state=random-state4. 交换访问令牌
curl -X POST http://localhost:5100/api/v6/idp/common/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "client_id=your-client-id" \
-d "client_secret=your-secret" \
-d "redirect_uri=https://your-app.com/callback"响应:
{
"access_token": "ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH_TOKEN",
"id_token": "ID_TOKEN"
}5. 获取用户信息
curl http://localhost:5100/api/v6/idp/common/userinfo \
-H "Authorization: Bearer ACCESS_TOKEN"响应:
{
"sub": "user-id",
"name": "John Doe",
"email": "[email protected]",
"email_verified": true,
"picture": "https://example.com/avatar.jpg"
}调试 OIDC Provider
使用 OIDC Debugger
访问 https://oidcdebugger.com/ 进行调试。
配置:
# Authorization Endpoint
http://localhost:5100/api/v6/idp/common/auth
# 环境变量
B6_OIDC_PROVIDER_CLIENT_ID=test
B6_OIDC_PROVIDER_CLIENT_SECRET=secret
B6_OIDC_PROVIDER_REDIRECT_URIS=https://oidcdebugger.com/debug测试客户端配置
// 快速测试配置
const testConfig = {
client_id: 'test',
client_secret: 'secret',
redirect_uris: ['https://oidcdebugger.com/debug'],
grant_types: ['authorization_code'],
response_types: ['code']
};客户端集成示例
JavaScript/TypeScript
import { Issuer, generators } from 'openid-client';
// 发现 OIDC 配置
const issuer = await Issuer.discover(
'http://localhost:5100/api/v6/idp/common'
);
// 创建客户端
const client = new issuer.Client({
client_id: 'your-client-id',
client_secret: 'your-secret',
redirect_uris: ['https://your-app.com/callback'],
response_types: ['code']
});
// 生成认证 URL
const code_verifier = generators.codeVerifier();
const code_challenge = generators.codeChallenge(code_verifier);
const authUrl = client.authorizationUrl({
scope: 'openid profile email',
code_challenge,
code_challenge_method: 'S256'
});
// 处理回调
const params = client.callbackParams(req);
const tokenSet = await client.callback(
'https://your-app.com/callback',
params,
{ code_verifier }
);
console.log('Access Token:', tokenSet.access_token);
console.log('ID Token:', tokenSet.id_token);
console.log('Refresh Token:', tokenSet.refresh_token);
// 获取用户信息
const userinfo = await client.userinfo(tokenSet.access_token);
console.log('User Info:', userinfo);Python
from authlib.integrations.requests_client import OAuth2Session
client = OAuth2Session(
client_id='your-client-id',
client_secret='your-secret',
redirect_uri='https://your-app.com/callback'
)
# 获取授权 URL
authorization_endpoint = 'http://localhost:5100/api/v6/idp/common/auth'
auth_url, state = client.create_authorization_url(
authorization_endpoint,
scope='openid profile email'
)
# 交换令牌
token_endpoint = 'http://localhost:5100/api/v6/idp/common/token'
token = client.fetch_token(
token_endpoint,
authorization_response=callback_url
)
# 获取用户信息
userinfo_endpoint = 'http://localhost:5100/api/v6/idp/common/userinfo'
userinfo = client.get(userinfo_endpoint).json()多租户支持
OIDC Provider 支持多租户模式,每个租户可以有独立的 OIDC 配置:
# 租户特定的配置端点
http://localhost:5100/api/v6/idp/{tenantId}/.well-known/openid-configuration
# 租户特定的认证端点
http://localhost:5100/api/v6/idp/{tenantId}/auth安全特性
- PKCE 支持: 支持 Proof Key for Code Exchange,增强公共客户端安全性
- State 参数: 防止 CSRF 攻击
- Nonce 验证: 防止重放攻击
- 密钥加密: 使用 bcrypt 加密客户端密钥
- 令牌过期: 可配置的令牌过期时间
- Refresh Token 轮换: 可选的刷新令牌轮换机制
使用场景
- 企业 SSO: 为企业内部应用提供统一认证
- 多应用集成: 多个应用共享一套用户体系
- 第三方应用接入: 允许第三方应用安全接入
- 移动应用认证: 为移动应用提供 OAuth 认证
- 微服务认证: 微服务架构中的统一认证网关
依赖项
主要依赖
oidc-provider: ^9.5.2 - OIDC 提供者核心库bcryptjs: ^3.0.3 - 密码加密lodash: ^4.17.21 - 工具函数库
Peer Dependencies
@builder6/core: ^3.0.10 - 核心功能模块@builder6/moleculer: ^3.0.10 - 微服务框架@nestjs/common: ^11.0.0 - NestJS 核心@nestjs/core: ^11.0.0 - NestJS 核心@nestjs/swagger: ^11.0.7 - API 文档
开发
构建
npm run build监听模式
npm run build:watch格式化代码
npm run format参考资源
License
MIT
