跳到主内容

概述

Casdoor基于OAuth构建,并使用令牌进行用户身份验证和授权。

访问令牌和ID令牌​

在Casdoor中,access_token与id_token是相同的。两者都包含相同的JWT有效载荷(用户信息和声明)。这种设计使令牌处理保持简单。

这种方法意味着:

  • 这两个令牌包含相同用户信息和自定义声明
  • 这两个令牌可互换用于身份验证和授权
  • 令牌格式和过期设置对这两个令牌同样适用
  • 不能为 access_token 和 id_token 分别配置不同的声明

令牌字段​

Casdoor 令牌包含以下字段:

  • Owner
  • Name
  • CreatedTime
  • Application
  • Organization
  • User
  • Code
  • AccessToken
  • ExpireIn(令牌将在几小时后过期)
  • Scope (授权范围)
  • TokenType(例如,Bearer 类型)

令牌生命周期与失效​

当用户登录时,Casdoor 会颁发一个访问令牌和一个刷新令牌。访问令牌用于 API 身份验证;刷新令牌用于在无需重新身份验证的情况下获取新的访问令牌。

SSO 登出时,Casdoor 会把 ExpiresIn 设为 0 或负数,使令牌失效。令牌自省和刷新接口会检查这个字段,拒绝 ExpiresIn <= 0 的令牌,所以登出后刷新令牌就不能再用了。这将导致所有标记类型会话完全终止。

自动清理过期令牌​

Casdoor 会自动删除已过期一段时间的令牌记录,避免 token 表无限增长。令牌过期超过 30 天的保留期(从令牌自身的过期时间算起)后会被删除。

清理任务的运行时机:

  • 启动时运行一次(在后台进行,不会拖慢服务器启动),以及
  • 每天午夜(服务器时间)运行。

清理只影响超过保留期的已过期令牌,绝不会动有效的令牌。这是内置行为,无需配置。

令牌格式选项​

在颁发JWT时,可从四种格式中进行选择:

  • JWT
  • JWT-Empty
  • JWT-Custom
  • JWT-标准

令牌格式选项的行为如下:

  • JWT:在令牌有效载荷中包含所有用户字段
  • JWT-空:仅包含非空用户字段
  • JWT-自定义:包含您选择的自定义用户令牌字段(在令牌字段中选择属性)
  • JWT标准:以符合OIDC的格式包含标准OIDC声明(电子邮件、电话、性别、地址)
信息

**只有 JWT-Standard 会生成符合 OIDC 规范的 address 声明。**在 JWT、JWT-Empty 和 JWT-Custom 格式中,address 字段是原始的 []string 数组(用户的 Address 属性),不符合 OIDC 规范。如果你的应用把 address 声明当作对象解析,请使用 JWT-Standard 令牌格式。

用 Token fields 限制字段​

应用上的 Token fields 设置(用于为 JWT-Custom 格式挑选自定义用户属性)同时也是 /userinfo 接口的白名单。

  • Token fields 为空时不启用白名单:令牌载荷和 /userinfo 响应都包含默认的全部字段。这是默认行为。
  • Token fields 列出了一个或多个字段时,只返回这些字段。不在列表中的用户属性,在 JWT-Custom 令牌载荷和 /userinfo 响应中都会被省略。

白名单按底层的用户属性名匹配。例如,要通过 /userinfo 返回显示名、邮箱和头像,把 Name、Email 和 Avatar 加到 Token fields。字段仍受申请的 OAuth scope 约束,例如只有授予了 email scope 才返回 Email,只有 address scope 才返回 Location(即 address 声明),只有 phone scope 才返回 Phone。无论白名单如何,sub 和 aud 声明总会返回。

注意事项

配置 Token fields 会限制 /userinfo,而不只是令牌。如果你之前依赖 /userinfo 返回所有字段,在这里添加条目后,该响应就会开始被过滤。要保持完整响应,就让 Token fields 留空。

OIDC 地址声明​

OIDC 规范 把 address 声明定义为包含以下字段的 JSON 对象:

字段描述
格式化完整邮寄地址,已格式化以便显示
街道地址街道地址组成部分(可能包含门牌号、街道名称、邮政信箱信箱等)
所在地城市或所在地
地区州、省、地级市或地区
邮政编码邮编或邮政编码
国家国家名称

Casdoor如何将用户数据映射到地址声明​

Casdoor在两个独立的用户字段中存储地址信息:

  • 位置(字符串):一个通用的位置字符串(例如,“纽约”). 请求 address scope 时,/api/userinfo 接口返回的纯字符串 address 值就取自这个字段。
  • 地址(字符串数组):地址行字符串数组(例如,["123 Main St", "Anytown, NY 12345", "USA"]). JWT-Standard 令牌中符合 OIDC 规范的 address 声明以这个字段为来源。

JWT-标准地址声明​

请求 address scope 并使用 JWT-Standard 格式时,Casdoor 会在令牌中返回如下对象:

{
"address": {
"street_address": "123 Main St\nAnytown, NY 12345\nUSA",
"formatted": "",
"locality": "",
"region": "",
"postal_code": "",
"country": ""
}
}

street_address 字段是用户 Address 数组中各项用换行符连接后的结果。其余的 OIDC 地址子字段(formatted、locality、region、postal_code、country)目前为空,因为 Casdoor 把整个地址以自由格式的多行文本存在 Address 数组中,而不是按组成部分分字段存储。

非标准格式(JWT、JWT-Empty、JWT-自定义)​

在 JWT、JWT-Empty 和 JWT-Custom 令牌格式中,address 字段是用户对象原始的 Address 属性,即一个字符串组成的 JSON 数组,而不是 OIDC 地址对象:

{
"address": ["123 Main St", "Anytown, NY 12345", "USA"]
}

按照 OIDC 规范期望 address 声明是 JSON 对象的 OIDC 客户端会解析失败。如果需要令牌中有符合规范的 address 声明,请切换到 JWT-Standard。

JWT-自定义

标准OIDC声明​

所有JWT令牌格式均在有效负载中包含这些标准OpenID Connect声明:

  • sub:主体标识(唯一的用户 ID)
  • email:用户的邮箱地址
  • email_verified- 布尔值,表示电子邮件是否已由Casdoor验证
  • name或preferred_username- 用户的显示名称
  • picture或avatar- 用户头像URL

有了 email_verified 声明,把 Casdoor 当作身份提供商的外部应用可以直接从令牌判断邮箱是否已验证,无需再调 API。

自定义令牌属性​

使用JWT-自定义格式,定义自定义属性及其数据类型。每个属性都包含一个类型字段,用于控制值如何包含在JWT中:

  • 数组:即使属性值仅包含一个元素,也始终以数组形式返回。这可确保与期望角色、组或权限等字段采用数组类型的OIDC客户端兼容。
  • 字符串:属性值将作为单个字符串返回(如果存在多个值,则返回第一个元素)。

空属性会自动从标记中省略,以保持有效负载的简洁。在为角色、组或权限配置属性时,建议使用数组类型,以更好地符合OIDC规范,并与Rancher和Keycloak等系统兼容。