ID 令牌声明参考
ID 令牌是 JSON Web 令牌 (JWT)。 v1.0 和 v2.0 ID 令牌所携带的信息有所不同。 版本基于终结点,从该终结点处其接受请求。 尽管现有应用程序可能会使用 Azure AD v1.0 终结点,但新应用程序应使用 v2.0 终结点。
- v1.0:
https://login.microsoftonline.com/common/oauth2/authorize
- v2.0:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
除非另行说明,否则以下各节列出的所有 JWT 声明在 v1.0 和 v2.0 令牌中均有出现。 ID 令牌由标头、有效负载和签名组成。 可以使用标头和签名来验证令牌的真实性,而有效负载则包含客户端请求的用户信息。
标头声明
下表显示了 ID 令牌中的标头声明。
声明 | 格式 | 说明 |
---|---|---|
typ |
字符串 - 始终为“JWT” | 指示令牌是 JWT 令牌。 |
alg |
String | 指示用于对令牌签名的算法。 示例:“RS256” |
kid |
字符串 | 指定可用于验证此令牌签名的公钥的指纹。 在 v1.0 和 v2.0 令牌中已发出。 |
x5t |
字符串 | 功能与 kid 相同(在用法和值方面)。 x5t 是在 v1.0 ID 令牌中仅出于兼容目的而发出的旧式声明。 |
有效负载声明
下表显示了默认情况下大多数 ID 令牌中的声明(除非另行注明)。 但是,应用可以使用可选声明来请求 ID 令牌中的其他声明。 可选声明的范围可以从 groups
声明到有关用户名称的信息。
声明 | 格式 | 说明 |
---|---|---|
aud |
字符串,应用 ID GUID | 标识令牌的目标接收方。 在 id_tokens 中,受众是在 Azure 门户中分配给应用的应用程序 ID。 应验证此值。 如果令牌无法与应用的应用程序 ID 匹配,则应拒绝。 |
iss |
字符串,证书颁发者 URI | 标识证书颁发者,或构造并返回令牌的“授权服务器”。 还标识在其中进行用户身份验证的租户。 如果令牌由 v2.0 终结点颁发,则 URI 以 /v2.0 结尾。 表示用户是来自 Microsoft 帐户的使用者用户的 GUID 为 9188040d-6c67-4c5b-b112-36a304b66dad 。 应用应该使用声明的 GUID 部分限制可登录应用的租户集(如果适用)。 |
iat |
int,Unix 时间戳 | 指示针对令牌进行身份验证的时间。 |
idp |
字符串,通常是 STS URI | 记录对令牌使用者进行身份验证的标识提供者。 除非用户帐户与颁发者不在同一租户中(例如,来宾),否则此值与颁发者声明的值相同。 如果声明不存在,则意味着可以改用 iss 的值。 对于在组织上下文中使用的个人帐户(例如,受邀加入租户的个人帐户),idp 声明可能是“live.com”或包含 Microsoft 帐户租户 9188040d-6c67-4c5b-b112-36a304b66dad 的 STS URI。 |
nbf |
int,Unix 时间戳 | 指示时间,在此时间之前不得接受 JWT 进行处理。 |
exp |
int,Unix 时间戳 | 指示过期时间,在此时间或之后不得接受 JWT 进行处理。 在某些情况下,资源可能会在此时间之前拒绝该令牌。 例如,如果需要更改身份验证或已检测到令牌吊销。 |
c_hash |
String | 仅当 ID 令牌随 OAuth 2.0 授权代码一起颁发时,代码哈希才包含在 ID 令牌中。 它可用于验证授权代码的真实性。 若要了解如何执行此验证,请参阅 OpenID Connect 规范。 来自 /token 终结点的 ID 令牌不会返回此声明。 |
at_hash |
String | 仅当 ID 令牌颁发自 /authorize 终结点并随 OAuth 2.0 访问令牌一起颁发时,访问令牌哈希才包含在 ID 令牌中。 它可用于验证访问令牌的真实性。 若要了解如何执行此验证,请参阅 OpenID Connect 规范。 来自 /token 终结点的 ID 令牌不会返回此声明。 |
aio |
不透明字符串 | 一个内部声明,用来记录有关重复使用令牌的数据。 应忽略。 |
preferred_username |
String | 表示用户的主用户名。 可以是电子邮件地址、电话号码或未指定格式的一般用户名。 其值是可变的,可能随时改变。 由于此值是可变的,因此不能用于做出授权决定。 它可以用于用户名提示,在人工可读的用户界面中用作用户名。 需要 profile 作用域才能接收此声明。 仅在 v2.0 令牌中提供。 |
email |
String | 对于具有电子邮件地址的来宾帐户,默认情况下会显示。 你的应用可以使用 email 可选声明为托管用户(来自与资源相同的租户)请求电子邮件声明。 不保证此值是正确的,它会随着时间的推移而改变。 切勿将其用于授权或为用户保存数据。 如果你的应用中需要可寻址的电子邮件地址,请直接向用户请求此数据,方法是将此声明用作建议或预先填写你的 UX。 在 v2.0 终结点上,应用程序还可以请求 email OpenID Connect 范围 - 你无需同时请求可选声明和范围来获取声明。 |
name |
String | 此 name 声明提供了标识令牌使用者的用户可读值。 此值不一定唯一,可以更改,仅用于显示目的。 需要 profile 作用域才能接收此声明。 |
nonce |
String | nonce 与发送给 IDP 的原始 authorize 请求中包含的参数匹配。 如果不匹配,应用程序会拒绝此令牌。 |
oid |
字符串,GUID | 对象的不可变标识符在这种情况下是用户帐户。 此 ID 唯一标识应用程序中的用户 - 同一个用户登录两个不同的应用程序会在 oid 声明中收到相同值。 Microsoft Graph 会返回此 ID 作为用户帐户的 id 属性。 因为 oid 允许多个应用关联用户,需要 profile 作用域才能收到此声明。 如果一个用户存在于多个租户中,该用户在每个租户中都有一个不同的对象 ID - 它们将视为不同帐户,即使用户使用相同的凭据登录到每个帐户,也是如此。 oid 声明是一个 GUID,不能重复使用。 |
roles |
字符串数组 | 分配给已登录用户的角色集。 |
rh |
不透明字符串 | 用来重新验证令牌的内部声明。 应忽略。 |
sub |
String | 令牌中信息的使用者。 例如,应用的用户。 此值是不可变的,无法重新分配或重复使用。 使用者是成对标识符,对应用程序 ID 是唯一的。 如果单个用户使用两个不同的客户端 ID 登录到两个不同的应用,这些应用将收到两个不同的使用者声明值。 根据体系结构和隐私要求,不一定需要两个值。 |
tid |
字符串,GUID | 表示用户登录到的租户。 对于工作和学校帐户,该 GUID 就是用户登录到的组织的不可变租户 ID。 对于登录个人 Microsoft 帐户租户(Xbox、Teams for Life 或 Outlook 等服务)的情况,值为 9188040d-6c67-4c5b-b112-36a304b66dad 。 |
unique_name |
字符串 | 仅在 v1.0 令牌中提供。 提供一个用户可读值,用于标识令牌使用者。 不保证此值在租户中唯一,只应该用于显示目的。 |
uti |
字符串 | 令牌标识符声明,等效于 JWT 规范中的 jti 。 区分大小写的唯一每令牌标识符。 |
ver |
字符串,1.0 或 2.0 | 指示 ID 令牌的版本。 |
hasgroups |
布尔 | 如果存在,始终为 true,表示该用户至少在一个组中。 指示客户端应当使用 Microsoft Graph API 来确定用户的组 (https://graph.microsoft.com/v1.0/users/{userID}/getMemberObjects )。 |
groups:src1 |
JSON 对象 | 对于长度不受限制(请参阅 hasgroups )但对于令牌而言仍然太大的令牌请求,会包括指向用户的完整组列表的链接。 对于 JWT,作为分布式声明;对于 SAML,作为新声明替代 groups 声明。 JWT 值示例: "groups":"src1" "_claim_sources : "src1" : { "endpoint" : "https://graph.microsoft.com/v1.0/users/{userID}/getMemberObjects" } 有关详细信息,请参阅组超额声明。 |
使用声明来可靠标识用户
标识用户时,使用长期不变而唯一的值非常重要。 旧版应用程序有时使用电子邮件地址、电话号码或 UPN 等字段。 从长远来看,所有这些字段都可能更改,也可能重复使用。 例如,当员工更改其姓名时,或者为员工提供的电子邮件地址与以前的、已不在职的员工的电子邮件地址相匹配时。 应用程序不应使用人工可读的数据来标识用户 - 可人工阅读通常意味着有人会阅读此信息并想要更改。 请改为使用由 OIDC 标准提供的声明,或使用由 Microsoft 提供的扩展声明 - sub
和 oid
声明。
要正确存储每个用户的信息,请仅使用 sub
或 oid
(因为 GUID 是唯一的),如果需要,可以与 tid
(用于路由或分片)一起使用。 如需跨服务共享数据,最好使用 oid
和 tid
,因为所有应用都将为在租户中操作的用户获得相同 oid
和 tid
声明。 sub
声明是唯一的成对值。 该值根据信息接收人、租户和用户的组合来确定。 为某用户请求 ID 令牌的两个应用将收到不同的 sub
声明,但会为该用户收到相同的 oid
声明。
注意
请不要为了尝试跨租户关联用户而使用 idp
声明来存储有关用户的信息。 这样不会起作用,因为按设计,用户的 oid
和 sub
声明在不同租户中会更改,以确保应用程序无法跨租户跟踪用户。
来宾方案(用户托管在一个租户中,在另一个租户中进行身份验证)应将用户视为服务的全新用户。 一个租户中的文档和特权不应在另一个租户中使用。 这一限制对于防止跨租户意外泄露数据以及强制执行数据生命周期非常重要。 将来宾逐出租户时,还应删除他们对在该租户中创建的数据的访问权限。
组超额声明
为确保令牌大小不超过 HTTP 标头的大小限制,在 groups
声明中包含的对象 ID 的数量是有限的。 如果某用户所属的组超过超额限制(对于 SAML 令牌,为 150;对于 JWT 令牌,为 200),则令牌中不会包含组声明。 但是,它会在令牌中包含超额声明,该声明指示应用程序查询 Microsoft Graph API 以检索用户的组成员身份。
{
...
"_claim_names": {
"groups": "src1"
},
{
"_claim_sources": {
"src1": {
"endpoint":"[Url to get this user's group membership from]"
}
}
}
...
}