我有一个用TypeScript编写的单页面应用程序。它需要调用中间层服务,而中间层服务将依次调用Microsoft Graph API。
在我的SPA中,我使用MSAL library,并通过调用UserAgentApplication.loginRedirect()让用户登录
然后,我调用acquireTokenPopup并在访问令牌请求参数中仅传递一个作用域:由中间层服务定义的作用域。执行此操作后,我会看到弹出窗口,但随后它会消失(我从未看到任何同意提示)。这将成功获取令牌,然后SPA将其作为HTTPS请求中Authorization标头上的持有者令牌发送到中间层。
然后,中间层尝试通过使用如下属性调用AAD来获取OBO令牌:
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";
它还具有在中间层的AAD注册中定义的客户端秘密。当向AAD端点发出此请求以检索OBO令牌时,它总是失败,并显示以下错误:
{"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不是发送交互式授权请求的正确方式,什么才是正确的方式?
可能有用的信息:
谢谢!
发布于 2019-05-23 09:42:26
首先,在您描述的场景中,您对代表流的使用看起来很好。
对于管理员同意部分(为了避免AADSTS65001错误),您可以尝试通过以下两种方式之一显式地进行同意:
转到Azure门户> Azure AD >应用程序注册>应用程序注册> API Permissions
然后点击“为你的广告授予管理员同意”按钮。
有关微软文档的更多信息,请单击此处- Request Permissions from Directory Admin
获取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用于管理同意端点。
https://stackoverflow.com/questions/56266148
复制相似问题