Azure AD v2 角色未包含在访问令牌中
Azure AD v2 roles not included in Access Token
我正在使用 https://login.microsoftonline.com/.../oauth2/v2.0/token 验证(authorization_code 授权)到 azure Ad 使用以下范围:offline_access、openid、profile、User.Read
根据文档,我收到的访问令牌应包含用户的角色:
https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens
然而只有身份令牌returns角色:
--Access Token
{
"typ": "JWT",
"nonce": "IWTwK2P0vzHoNnv1vvvSsjZSbAYPpSIk8MozY0A4WR0",
"alg": "RS256",
"x5t": "nOo3ZDrODXEK1jKWhXslHR_KXEg",
"kid": "nOo3ZDrODXEK1jKWhXslHR_KXEg"
}.{
...
"rh": "0.ASgASPp-HouAsUyXCdG05vvfeHAoPPG46TFOoWYsil-LDcsoADw.",
"scp": "User.Read profile openid email",
...
}.[Signature]
--Identity Token
{
"typ": "JWT",
"alg": "RS256",
"kid": "nOo3ZDrODXEK1jKWhXslHR_KXEg"
}.{
...
"rh": "0.ASgASPp-HouAsUyXCdG05vvfeHAoPPG46TFOoWYsil-LDcsoADw.",
"roles": [
"MyApp.Read",
"MyApp.Admin",
"MyApp.Write",
],
...
}.[Signature]
有没有办法让访问令牌也包含角色?
感谢@juunas 的提示,@juunas 是对的。如果您使用的是自定义 api,用户令牌还可以包含 roles
声明。
您需要在 Azure 中创建两个应用程序,一个代表 客户端应用程序,另一个代表 api 应用程序 ,然后使用客户端应用程序调用 api 应用程序。
首先需要暴露受Azure保护的后端应用API,并添加客户端应用:
接下来需要设置apiapplicationAppRole,这是你自定义的角色,会显示在manifest中。
然后您可以将角色分配给用户。转到企业应用程序 > 您的 api 应用程序 > 用户和组。
接下来,转到客户端应用程序,让您的客户端应用程序访问您的后端 api:
- 在 'API permissions' 下单击 'Add permission',然后单击“我的 APIs”选项卡。
- 找到您的后端应用程序和select适当的范围。
- 点击'Add permissions'。
- 为您的 API 授予管理员许可。
接下来,您需要使用auth code flow获取访问令牌,这需要您登录用户并获取授权码,然后使用授权码兑换访问令牌。
解析令牌,它同时包含 scp
声明和 roles
声明。
不幸的是,AAD 上存在一个错误,仅在请求令牌时请求 API 范围时才将角色添加到 access_token。
为了让角色发挥作用,您需要进行以下设置:
- 创建应用程序
- 使用“公开 API”向应用程序添加作用域
- 请求令牌时使用在上述步骤中创建的范围
最终结果将是一个代币
示例:
https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize?client_id={appid}&response_type=token&scope={appid}/{scopename}&nonce=678910
范围 openid
、email
和 profile
只能与 id_tokens
一起使用
如果您要在 Azure Active Directory 的应用程序注册中注册 API 应用程序并通过也在 Azure Active Directory 中注册的 SPA 应用程序公开它,那么-
- id 令牌包含在 SPA 应用程序上公开的角色,并且
- 访问令牌包含在 API 应用程序上公开的角色。
(这是我从 Carl Zhao 的回答中得到的重要信息)
我正在使用 https://login.microsoftonline.com/.../oauth2/v2.0/token 验证(authorization_code 授权)到 azure Ad 使用以下范围:offline_access、openid、profile、User.Read
根据文档,我收到的访问令牌应包含用户的角色: https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens
然而只有身份令牌returns角色:
--Access Token
{
"typ": "JWT",
"nonce": "IWTwK2P0vzHoNnv1vvvSsjZSbAYPpSIk8MozY0A4WR0",
"alg": "RS256",
"x5t": "nOo3ZDrODXEK1jKWhXslHR_KXEg",
"kid": "nOo3ZDrODXEK1jKWhXslHR_KXEg"
}.{
...
"rh": "0.ASgASPp-HouAsUyXCdG05vvfeHAoPPG46TFOoWYsil-LDcsoADw.",
"scp": "User.Read profile openid email",
...
}.[Signature]
--Identity Token
{
"typ": "JWT",
"alg": "RS256",
"kid": "nOo3ZDrODXEK1jKWhXslHR_KXEg"
}.{
...
"rh": "0.ASgASPp-HouAsUyXCdG05vvfeHAoPPG46TFOoWYsil-LDcsoADw.",
"roles": [
"MyApp.Read",
"MyApp.Admin",
"MyApp.Write",
],
...
}.[Signature]
有没有办法让访问令牌也包含角色?
感谢@juunas 的提示,@juunas 是对的。如果您使用的是自定义 api,用户令牌还可以包含 roles
声明。
您需要在 Azure 中创建两个应用程序,一个代表 客户端应用程序,另一个代表 api 应用程序 ,然后使用客户端应用程序调用 api 应用程序。
首先需要暴露受Azure保护的后端应用API,并添加客户端应用:
接下来需要设置apiapplicationAppRole,这是你自定义的角色,会显示在manifest中。
然后您可以将角色分配给用户。转到企业应用程序 > 您的 api 应用程序 > 用户和组。
接下来,转到客户端应用程序,让您的客户端应用程序访问您的后端 api:
- 在 'API permissions' 下单击 'Add permission',然后单击“我的 APIs”选项卡。
- 找到您的后端应用程序和select适当的范围。
- 点击'Add permissions'。
- 为您的 API 授予管理员许可。
接下来,您需要使用auth code flow获取访问令牌,这需要您登录用户并获取授权码,然后使用授权码兑换访问令牌。
解析令牌,它同时包含 scp
声明和 roles
声明。
不幸的是,AAD 上存在一个错误,仅在请求令牌时请求 API 范围时才将角色添加到 access_token。
为了让角色发挥作用,您需要进行以下设置:
- 创建应用程序
- 使用“公开 API”向应用程序添加作用域
- 请求令牌时使用在上述步骤中创建的范围
最终结果将是一个代币
示例:
https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize?client_id={appid}&response_type=token&scope={appid}/{scopename}&nonce=678910
范围 openid
、email
和 profile
只能与 id_tokens
如果您要在 Azure Active Directory 的应用程序注册中注册 API 应用程序并通过也在 Azure Active Directory 中注册的 SPA 应用程序公开它,那么-
- id 令牌包含在 SPA 应用程序上公开的角色,并且
- 访问令牌包含在 API 应用程序上公开的角色。
(这是我从 Carl Zhao 的回答中得到的重要信息)