请求 Microsoft Graph 委派权限时,没有为 AD B2C 用户返回访问令牌令牌、权限、用户、Microsoft

2023-09-06 16:58:54 作者:来包辣条压压惊

用户故事:给定一个 ADB2C 用户,具有全局管理员角色和 01234567-901a-bcde-f012-3456789abcde 的 oid(不是真正的 oid),我希望能够登录作为该用户并从

在仅分配了 Microsoft Graph 权限范围的应用注册中,我使用邮递员请求不记名令牌以访问 MS Graph.有一个 Web 重定向 URI (https://oauth.pstmn.io/v1/callback),一个客户端密钥,并且对访问和 id 令牌都启用了隐式授权.

Microsoft Graph 桌面应用程序

请求的范围是:openid offline_access https://graph.microsoft.com/Directory.AccessAsUser.All

同样,B2C 用户帐户具有全局管理员角色.

隐式流返回错误消息

AADB2C90205:此应用程序对此 Web 资源没有足够的权限来执行该操作.

授权码流,当包含应用程序机密时,缺少访问承载令牌.有一个 ID 令牌和一个刷新令牌,但没有访问令牌.无论我是否将授权发送到外部浏览器,都有和没有 PKCE.

我租户中的应用程序有一个用户流,B2C_1_postman,基本上是默认的.它适用于邮递员、其他测试应用程序以及 B2C 管理刀片中的运行用户流"功能.

身份验证端点是:

https://{Tenant}.b2clogin.com/{Tenant}.onmicrosoft.com/B2C_1_postman/oauth2/v2.0/authorize

令牌端点是:

https://{Tenant}.b2clogin.com/{Tenant}onmicrosoft.com/B2C_1_postman/oauth2/v2.0/token

我已经通过 Microsoft 的 github 存储库中的几个桌面演示复制了这种行为,现在使用 Postman.该应用程序名为邮递员",位于 ADB2C 租户中.我授予它以下应用 API 范围:

Directory.AccessAsUser.All目录.阅读.全部Directory.ReadWrite.All目录.emailDirectory.offline_access目录.profile

此过程反映了 https://github 上的桌面演示.com/Azure-Samples/active-directory-b2c-dotnet-desktop 设置,唯一的例外是我希望我的桌面应用程序使用 MS Graph 而不是 NodeJS 示例应用程序.(如果我为示例应用添加端点,这个应用注册就可以正常工作.但指定 MS Graph 范围总是返回一个空的访问 ID.)

我怎样才能让它工作?

解决方案

通过 Graph API 管理用户似乎仍然需要使用应用程序权限.因此,您需要添加应用程序权限,而不是在 B2C 中向应用程序添加委派权限,在此您将 Graph API 作为应用程序调用,而不是代表用户.文档中的说明详细解释了应用注册:https://docs.microsoft.com/en-us/azure/active-directory-b2c/microsoft-graph-get-started

您需要将此应用应用权限授予 Graph API,而不是委托权限.然后纯粹使用这些应用程序凭据来调用 Graph API.而且您需要使用底层 Azure AD 的令牌端点,而不是您的 B2C 策略令牌端点.

由于您的应用是桌面应用(公共客户端应用),您需要在后端服务中进行 Graph API 交互,您可以使用代表用户获取的 B2C 令牌对其进行身份验证.

User Story: Given an ADB2C User, with Global Administrator role and an oid of 01234567-901a-bcde-f012-3456789abcde (not a real oid), I want to be able to log in as that user and retrieve the user profile from "https://graph.microsoft.com/beta/me" or "https://graph.microsoft.com/beta/users/01234567-901a-bcde-f012-3456789abcde". Both are listed in the documentation as valid endpoints for B2C.

It's not working:

In an app registration with only Microsoft Graph permission scopes assigned, I used postman to request a bearer token for access to MS Graph. There is one Web redirect URI (https://oauth.pstmn.io/v1/callback), one client secret, and implicit grant is on for both access and id tokens.

The scopes requested are: openid offline_access https://graph.microsoft.com/Directory.AccessAsUser.All

Again, the B2C user account has the Global Administrator role.

The Implicit flow returns the error message

AADB2C90205: This application does not have sufficient permissions against this web resource to perform the operation.

The Authorization Code flow, when the app secret is included, lacks an access bearer token. There is an ID token and a refresh token, but no access token. That's with and without PKCE, whether or not I send the authorization to an external browser.

The app in my tenant has a user flow, B2C_1_postman, which is basically default. It works just fine with postman, other test apps, and the "Run User Flow" function in the B2C management blade.

The auth endpoint is:

https://{Tenant}.b2clogin.com/{Tenant}.onmicrosoft.com/B2C_1_postman/oauth2/v2.0/authorize

The token endpoint is:

https://{Tenant}.b2clogin.com/{Tenant}onmicrosoft.com/B2C_1_postman/oauth2/v2.0/token

I've duplicated this behavior with a couple of desktop demos from Microsoft's github repository, and now with Postman. The app, called "postman", is in the ADB2C tenant. I granted it the app API scopes of:

Directory.AccessAsUser.All
Directory.Read.All
Directory.ReadWrite.All
Directory.email
Directory.offline_access
Directory.profile

This procedure mirrors what the desktop demo at https://github.com/Azure-Samples/active-directory-b2c-dotnet-desktop sets up, with the single exception being that instead of a NodeJS sample app, I want my desktop app to use MS Graph. (This app registration works just fine if I add the endpoints for the sample app. But specifying the MS Graph scopes always returns an empty access ID.)

How can I get this to work?

解决方案

Managing users through Graph API still seems to require usage of application permissions. So instead of adding delegated permissions to the app in B2C, you need to add application permissions, where you call the Graph API as the app, not on behalf of the user. The instructions in the docs explain the app registration in detail: https://docs.microsoft.com/en-us/azure/active-directory-b2c/microsoft-graph-get-started

You need to give this app application permissions to Graph API, not delegated permissions. Then use those app credentials purely to call Graph API. And you need to use the underlying Azure AD's token endpoint instead of your B2C policy token endpoint.

Since your app is a desktop app (a public client app), you'll need to do the Graph API interactions in a back-end service to which you can authenticate with a B2C token acquired on behalf of the user.