OIDC提供商
OIDC提供商插件使您能够构建和管理自己的OpenID Connect (OIDC)提供商,让您完全控制用户身份验证,而无需依赖Okta或Azure AD等第三方服务。它还允许其他服务通过您的OIDC提供商验证用户身份。
主要特性:
- 客户端注册:注册客户端以通过您的OIDC提供商进行身份验证。
- 动态客户端注册:允许客户端动态注册。
- 授权码流程:支持授权码流程。
- JWKS端点:发布JWKS端点,允许客户端验证令牌。(尚未完全实现)
- 刷新令牌:颁发刷新令牌并使用
refresh_token
授权处理访问令牌更新。 - OAuth同意:实现OAuth同意界面用于用户授权,具有为受信任应用程序绕过同意的选项。
- UserInfo端点:为客户端提供UserInfo端点以获取用户详细信息。
此插件正在积极开发中,可能不适合生产环境使用。请在GitHub上报告任何问题或错误。
安装
使用方法
安装后,您可以使用OIDC提供商来管理应用程序内的身份验证流程。
注册新客户端
要注册新的OIDC客户端,请使用oauth2.register
方法。
创建应用程序后,您将收到可以显示给用户的client_id
和client_secret
。
此端点支持符合RFC7591的客户端注册。
UserInfo端点
OIDC提供商包括一个UserInfo端点,允许客户端检索已认证用户的信息。此端点位于/oauth2/userinfo
,需要有效的访问令牌。
UserInfo端点根据授权期间授予的作用域返回不同的声明:
- 使用
openid
作用域:返回用户的ID(sub
声明) - 使用
profile
作用域:返回姓名、头像、名字、姓氏 - 使用
email
作用域:返回电子邮件和电子邮件验证状态
getAdditionalUserInfoClaim
函数接收用户对象和请求的作用域数组,允许您根据授权期间授予的作用域有条件地包含声明。这些额外的声明将包含在UserInfo端点响应和ID令牌中。
同意界面
当用户被重定向到OIDC提供商进行身份验证时,他们可能会被提示授权应用程序访问他们的数据。这被称为同意界面。默认情况下,Better Auth将显示一个示例同意界面。您可以通过在初始化期间提供consentPage
选项来自定义同意界面。
插件将把用户重定向到指定的路径,并携带client_id
和scope
查询参数。您可以使用此信息显示自定义同意界面。一旦用户同意,您可以调用oauth2.consent
来完成授权。
client_id
和其他必要信息存储在浏览器cookie中,因此您不需要在请求中传递它们。如果它们在cookie中不存在,consent方法将返回错误。
处理登录
当用户被重定向到OIDC提供商进行身份验证时,如果他们尚未登录,将被重定向到登录页面。您可以通过在初始化期间提供loginPage
选项来自定义登录页面。
您不需要从您的一方处理任何事情;当创建新会话时,插件将处理继续授权流程。
配置
OIDC元数据
通过在初始化期间提供配置对象来自定义OIDC元数据。
JWKS端点(尚未完全实现)
对于JWKS支持,您需要使用jwt
插件。它公开/jwks
端点以提供公钥。
目前,令牌是用应用程序的密钥签名的。JWKS端点尚未完全实现。
动态客户端注册
如果您想允许客户端动态注册,可以通过将allowDynamicClientRegistration
选项设置为true
来启用此功能。
这将允许/register
端点公开可用,客户端可以使用它进行注册。
架构
OIDC提供商插件向数据库添加了以下表:
OAuth应用程序
表名:oauthApplication
Field Name | Type | Key | Description |
---|---|---|---|
id | string | OAuth客户端的数据库ID | |
clientId | string | 每个OAuth客户端的唯一标识符 | |
clientSecret | string | - | OAuth客户端的密钥 |
name | string | - | OAuth客户端的名称 |
redirectURLs | string | - | 重定向URL的逗号分隔列表 |
metadata | string | OAuth客户端的附加元数据 | |
type | string | - | OAuth客户端的类型(例如,web,移动) |
disabled | boolean | - | 指示客户端是否已禁用 |
userId | string | 拥有该客户端的用户的ID。(可选) | |
createdAt | Date | - | 创建OAuth客户端的时间戳 |
updatedAt | Date | - | 上次更新OAuth客户端的时间戳 |
OAuth访问令牌
表名:oauthAccessToken
Field Name | Type | Key | Description |
---|---|---|---|
id | string | 访问令牌的数据库ID | |
accessToken | string | - | 颁发给客户端的访问令牌 |
refreshToken | string | - | 颁发给客户端的刷新令牌 |
accessTokenExpiresAt | Date | - | 访问令牌的过期日期 |
refreshTokenExpiresAt | Date | - | 刷新令牌的过期日期 |
clientId | string | OAuth客户端的ID | |
userId | string | 与令牌关联的用户的ID | |
scopes | string | - | 授予的作用域的逗号分隔列表 |
createdAt | Date | - | 创建访问令牌的时间戳 |
updatedAt | Date | - | 上次更新访问令牌的时间戳 |
OAuth同意
表名:oauthConsent
Field Name | Type | Key | Description |
---|---|---|---|
id | string | 同意的数据库ID | |
userId | string | 给予同意的用户的ID | |
clientId | string | OAuth客户端的ID | |
scopes | string | - | 同意的作用域的逗号分隔列表 |
consentGiven | boolean | - | 指示是否给予了同意 |
createdAt | Date | - | 给予同意的时间戳 |
updatedAt | Date | - | 上次更新同意的时间戳 |
选项
allowDynamicClientRegistration: boolean
- 启用或禁用动态客户端注册。
metadata: OIDCMetadata
- 自定义OIDC提供商元数据。
loginPage: string
- 自定义登录页面的路径。
consentPage: string
- 自定义同意页面的路径。
getAdditionalUserInfoClaim: (user: User, scopes: string[]) => Record<string, any>
- 获取额外用户信息声明的函数。