Link Search Menu Expand Document
  1. Token有效期
  2. 什么是Claims
  3. 访问令牌解析(Access Token)
    1. 令牌格式
    2. 预留的scopes和claims
    3. 自定义的scopes和claims
  4. 身份令牌(ID Token) 解析
    1. 令牌格式
    2. 基本Claims(始终存在)
    3. 依赖于scope的claims(不始终返回)
  5. Refresh Token

Token有效期

当使用OneAuth内置的授权服务器时,生成的token有效期是固定的:

  • Access token :1小时
  • ID token :1小时
  • Refresh token :90天

当使用自定的授权服务器时,token有效期是可以配置的:

  • Access token :最小3分钟,最大24小时(在自定义授权服务器的访问策略中配置)
  • Refresh token :最小3分钟,最大999天。(在自定义授权服务器的访问策略中配置)
  • ID token : 不可以配置,有效期固定为1小时

什么是Claims

OneAuth颁发的token中包含一组用于描述主体(用户)的claims,如姓名、身份、权限等。token的类型决定了其中的claims,token在类型有两种:用于认证用户,用于认证应用程序。

当使用access token请求/userinfo端点时,返回的是与access token中指定的scopeprofileemailphoneaddress 所对应claims 。但当未颁发access token时(这是response_type 值为 id_token 时的情况),claims的值将在包含在 ID token中。

访问令牌解析(Access Token)

注:对access token的使用会根据您使用的是OneAuth内置授权服务器还是自定义授权服务器有所不同。由自定义授权服务器颁发的access token的结构是不会改变的,但是由OneAuth内置授权服务器颁发的access token的结构可能会发生变化。

access token 是一个使用Base64 URL 编码格式的JWT(JSON web token ),它包含了Header(头)、payload和签名三部分。资源服务器可以根据access token中的scopes和claims来授权客户端访问特定资源。

在自义授权服务器的访问策略中可以配置access token的有效期。如果颁发token的客户端被停用,token将立即永久失效,即使重新激活客户端不会使token再次有效。

令牌格式

access token的 Header

{
  "alg": "RS256",
  "kid": "45js03w0djwedsw"
}

access token的 payload

{
  "ver": 1,
  "jti": "AT.sdotTcWK5_oCxUf1521HNhG4hD4zrboaf0HExDEgmqk",
  "iss": "https://domain.oneauth.cn/oauth/v1/0oacqf8qaJw56czJi0g4",
  "aud": "https://api.example.com",
  "sub": "userName",
  "iat": 1634807022,
  "exp": 1634810622,
  "cid": "0oa4kxu5gaeV6M1yr696",
  "uid": "00u4j6wy5gYz4csRa696",
  "scp": [
    "openid",
    "email",
    "phone",
    "custom"
  ],
  "custom_claim": "CustomValue"
}

access token的签名

access token的签名是使用header部分中的 Kid 所标识的公钥生成的数字签名。

access token 、scopes和claims

access token中包括预留的scopes和claims,同时可以选择性地包括自定义的scopes和claims。

在第一步向授权服务器发起的的授权请求中(/authorization)包含了本次请求的scopes,授权服务器根据访问策略来决定是否可以授予它们。

然后根据授予的scope,将对应的claims添加到返回的access token中。

预留的scopes和claims

OneAuth 定义了一些预留的scopes和claims。

  • 预留的scopes
  • 在Header中预留的claims
  • 在payload中预留的claims

预留的 scopes

在OneAuth中预留了以下几个OIDC标准规定的scope:openidprofileemailphoneaddressoffline_access,这些scopes在OneAuth的内置授权服务器和自定义授权服务器中都是可用的。

在Header中预留的claims

在header中只有以下两个claims:

     
claims 描述 类型
alg 用于标识使用的签名算法,通常是rs256 String
kid 签发token所使用的签名所使用的公钥标识 String

在payload中预留的claims

在payload中预留了以下几个claims:

     
claims 描述 类型
cid 请求access token的客户端的client ID String
exp access token的过期时间,使用Unix标准时 Integer
iat 颁发access token的时间,使用Unix标准时 Integer
iss 颁发access token的授权服务器的标识 String
jti access token的唯一标识符,用于调试和撤销 String
scp 该access token中所授予的scopes Array
uid 用户的身份标识。当没有关联的用户时access token不包含该claim String
ver access token的语法版本 Integer

自定义的scopes和claims

在OneAuth的自定义授权服务器中,您可以为access token配置自定义的scopes和claims。

自定义的scopes

当一个生成access tokenr的请求中包含自定义的scope时,请求中的这些自定义scopes将与 OIDC 规范提供的scopes一起成为claim: scp的一部分。自定义scope的名称必须符合OAuth2的规范

注:Scope名称中可以包含<>,但是二者不能同时存在。 (于洋备注:这点与Scope中的约定相悖。)

自定义的Claims

自定义claims是与scopes相关联的。通常情况下,授予自定义scope意味着将自定义的claims添加到token中。但是具体还取决于请求哪些claims或其它配置的选择。

参考:token和claims的对应关系

自定义claims在自定义授权服务器中进行配置,token中包含哪些claims取决于多种因素,包括请求中scopes关联了哪些claims、请求的token类型、在授权服务器中token与claim的配置:

  • 内置授权服务器和自定义授权服务器颁发的access token和ID token中始终包含基本claims(预留的claims)
  • 根据授权服务器的responesType在token中返回依赖于scope的claims。请在Scope-dependent claims的第二个表格中查看详情。
  • 自定义Claims需要在自定义授权服务器中进行配置,您可以指定始终或仅在请求时在每个token(ID token 或access token)中返回claims。在没有请求access token时,如果claim与请求中的scopes匹配则在ID token中返回。

ID token和access token中可能不包括所有与请求的scopes关联的claims,但是在/userinfo端点中始终包含与scope关联的所有claims。

身份令牌(ID Token) 解析

在OIDC协议中引入了一个 ID token,它是一个 JSON Web token (JWT),在ID token中包含有关身份验证事件的信息和验证通过后用户的声明(claims)。

客户端可以使用以下任意操作来获取ID token:

  • Authorization code或Authorization code + PKCE 模式:客户端从授权服务器的/authorize端点取得授权码(Authorization code),然后使用授权码向授权服务器的/token端点换取ID token 和access token
  • Implicit 模式:客户端直接从授权服务器的/authorize端点获取ID token 以及access token

客户端应当始终验证ID token以确保其完整性。

通过以上介绍了两种获取ID token的方法(从/authorize端点获取、通过授权码从/token端点获取取)所取得的ID token都是完全相同的,除了以下情形:

  • 在Implicit模式下,在初始/authorize请求中需要nonce参数,此时在 ID token中将有一个名为 nonceclaim,应验证该claim以确保它与传递给 /authorize 的 nonce 值匹配。
  • 在ID token和access token都生成了的情况下, ID token中将包含一个 at_hash 参数,该参数可以由access token的哈希值来进行验证,以确保access token的是真实的。

令牌格式

ID token的Header

{
  "alg": "RS256",
  "kid": "8rB7hRasIdvwxZu2IujzBRSI-oitxtB9CjvAtewNXIw"
}

ID token的payload

{
  "ver": 1,
  "sub": "userName",
  "iss": "https://domain.oneauth.cn",
  "aud": "https://api.example.com",
  "iat": 1634807022,
  "exp": 1634810622,
  "amr": [
    "pwd"
  ],
  "jti": "ID.4eAWJOCMB3SX8XewDfVR",
  "auth_time": 1449624026,
  "at_hash": "cpqKfdQA5eH891Ff5oJr_Q",
  "name" :"Zhang San",
  "nickname":"Sam",
  "given_name":"San",
  "family_name":"Zhang",
  "profile":"https://example.com/john.doe",
  "zoneinfo":"CN/Hangzhou",
  "locale":"CN",
  "updated_at":1311280970,
  "email":"zhang@example.com",
  "email_verified":true,
  "address" : { "street_address": "文一西路1818-2号",
      "locality": "杭州",
      "region": "浙江",
      "postal_code": "310000",
      "country": "CN"
    },
  "phone_number":"+86 0571-12345678"
}

ID token的签名

ID token的签名是使用header部分中的 Kid 所标识的公钥生成的数字签名。

ID token的Claims

在ID token的Header和payload 中包含了calims

Header中的Claims

在ID token的header中始终返回claims:

claims 描述 类型
alg 用于标识使用的签名算法,通常是rs256 String
kid 签发token所使用的签名所使用的公钥标识 String

Payload中的Claim

ID token中的calims包含基本claims、独立不依赖于scope的claims(始终返回)、依赖于scope的claims(不始终返回)

基本Claims(始终存在)

claims 描述 类型 示例
amr 用户描述本次所使用的身份认证方式的JSON数组。查看Authentication Methods Array [ “pwd”, “mfa”, “otp”, “kba”, “sms”, “swk”, “hwk” ]
aud 该ID token的受众(audience)标识,它的值将是应用的Client ID String 0oa4kxu5gaeV6M1yr696
auth_time 终端用户验证成功的时间,使用Unix标准时 Integer 1634623310
exp ID token的过期时间,使用Unix标准时 Integer 1634810622
iat 颁发ID token的时间,使用Unix标准时 Integer 1634807022
idp OneAuth的租户ID,当是使用其它IdP认证时是IdP的ID (标准里不存在的) String 00ok1u7AsAkrwdZL3z0g3
iss 颁发ID token的授权服务器的标识 String http://custom.oneauth.cn
jti ID token的唯一标识符,用于调试和撤销 String Tlenfse93dgkaksginv
sub 主体,用户的身份标识(根据映射关系赋值) String zhangsan
ver ID token签名语法版本 Integer 1

依赖于scope的claims(不始终返回)

属性/claim Scope 描述 类型 示例
name profile 用户的全名. String John Doe
preferred_username profile The OneAuth login (username) for the end user. String john.doe@example.com
nickname profile 昵称 String Jimmy
preferred_username profile The chosen login (username) for the end user. By default this is the OneAuth username. String zhangsan@example.com
given_name profile String san
middle_name profile 中间名 String  
family_name profile String zhang
updated_at profile 用户信息最近一次更新的时间,使用Unix标准时 Integer 1311280970
email email 用户的电子信箱 String zhangsan@example.com
email_verified email 用户的email是否经过验证 boolean true
address address 用户的邮寄地址,JSON结构的数据,它包括: street_address, locality, region, postal_code, country. JSON structure { "street_address": "文一西路1818-2号", "locality": "杭州", "region": "浙江", "postal_code": "310000", "country": "CN" }
phone_number phone 用户的电话号码 String +86 0571-12345678
phone_number_verified phone 用户的phone_number是否经过验证 boolean true

重要:请求中的response_tpye和所请求的scopes决定了返回的信息中包含哪些依赖于scope的claims

Response Type 内置授权服务器颁发的ID token中的Caims 自定义授权服务器颁发的ID token中的Caims Userinfo 端点返回的claims
code N/A N/A N/A
token N/A N/A N/A
id_token 与请求的scopes相关联的claims 与请求的scopes相关联的claims N/A
id_token code 与请求的scopes相关联的claims 与请求的scopes相关联的claims N/A
id_token token 如果请求了scope: email 返回email ; 如果请求了scope: phone 返回phone_number ; 如果请求了scope: profile 返回name 与请求的scopes相关联的claims,以及配置为一直包含该claim 的自定义claims 与请求的scopes相关联的claims
code id_token token 如果请求了scope: email 返回email ; 如果请求了scope: phone 返回phone_number ; 如果请求了scope: profile 返回name ; 与请求的scopes相关联的claims,以及配置为一直包含该claim 的自定义claims 与请求的scopes相关联的claims

通过使用access token访问/userinfo端点可以取得所请求的scopes中所包含的全部完整的claims

Refresh Token

Refresh Token是个不透明的令牌。更多的信息参考获取刷新令牌