我有一个用 TypeScript 编写的单页应用程序。它需要调用中间层服务,而中间层服务又会调用 Microsoft Graph API。
在我的 SPA 中,我使用 MSAL library我通过调用 UserAgentApplication.loginRedirect() 登录用户
然后,我调用 acquireTokenPopup 并在访问 token 请求参数中仅传递一个范围:由我的中间层服务定义的范围。执行此操作后,我看到弹出窗口,但随后它消失了(我从未看到任何同意提示)。这成功获取了一个 token ,然后 SPA 将其作为 HTTPS 请求中授权 header 上的承载 token 发送到中间层。
然后,中间层尝试通过调用具有如下属性的 AAD 来获取 OBO token :
const grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer";
const assertion = userAccessToken;
const scope = "https://graph.microsoft.com/Calendars.Read " +
"https://graph.microsoft.com/Calendars.Read.Shared " +
"https://graph.microsoft.com/Calendars.ReadWrite " +
"https://graph.microsoft.com/Calendars.ReadWrite.Shared " +
"openid profile email offline_access";
const requestedTokenUse = "on_behalf_of";
它还有一个发送的客户端 key ,该 key 是在中间层的 AAD 注册中定义的。当向 AAD 端点发出此请求以检索 OBO token 时,它总是失败并出现以下错误:
{"error":"invalid_grant","error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID '<ID of middle-tier application>' named '<name of middle-tier application>'. Send an interactive authorization request for this user and resource.\r\nTrace ID: 39d9bace-03f0-402b-9310-c713aa990200\r\nCorrelation ID: edfbb88f-5c63-4cef-84c1-0de8457852b7\r\nTimestamp: 2019-05-22 22:25:24Z","error_codes":[65001],"timestamp":"2019-05-22 22:25:24Z","trace_id":"39d9bace-03f0-402b-9310-c713aa990200","correlation_id":"edfbb88f-5c63-4cef-84c1-0de8457852b7","suberror":"consent_required"}
我看到一些关于需要同意以及我应该如何发送交互式授权请求的内容 - 但我不确定如何做到这一点。事实上,当我最初调用 acquireTokenPopup(而不是 acquireTokenSilent)时,我认为我正在这样做。
如果在具有中间层定义范围的 SPA 客户端中调用 acquireTokenPopup 不是发送交互式授权请求的正确方法,那么什么是?
可能有用的信息:
- 我的 SPA 客户端应用程序的 ID 列在中间层 AAD 注册门户的“授权客户端应用程序”部分以及 list 的“knownClientApplications”部分中。
谢谢!
最佳答案
首先,您在所描述的场景中使用代表流程看起来不错。
对于管理员同意部分(为了克服 AADSTS65001 错误),您可以尝试通过以下两种方式之一明确同意:
使用 Azure 门户(适用于单租户应用程序)
转到 Azure 门户 > Azure AD > 应用程序注册 > 应用程序注册 > API 权限 然后点击“授予[您的 AD] 管理员同意”按钮。
使用管理员同意端点(适用于单租户或 Multi-Tenancy 应用)
有关 Microsoft 文档的更多信息,请参见此处 - Request Permissions from Directory Admin
GET https://login.microsoftonline.com/{tenant}/adminconsent? client_id=6731de76-14a6-49ae-97bc-6eba6914391e &state=12345 &redirect_uri=http://localhost/myapp/permissions
这里唯一的强制参数是
client_id
。您可以跳过提供其他参数,并且同意仍然有效。
顺便说一句,您提到的有关 knownClientApplications
的部分可以帮助解决更高级的场景,即您尝试在一次交互中合并多个应用程序的同意。就像同一个逻辑应用程序的多个层一样。如果这就是您想要实现的目标,那么您实际上不需要单独同意中间层 API。在这种情况下,您仍然可以使用方法 2 作为管理员同意端点。
关于azure - AAD : How do you send an "interactive authorization request" to resolve AADSTS65001 when using MSAL if it's not by calling acquireTokenPopup?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56266148/