AAD:使用 MSAL 时,如果不是通过调用 acquireTokenPopup,如何发送“交互式授权请求”来解析 AADSTS65001?

Aut*_*ant 10 azure azure-active-directory azure-ad-msal

我有一个用 TypeScript 编写的单页应用程序。它需要调用中间层服务,而中间层服务将依次调用 Microsoft Graph API。

在我的 SPA 中,我使用MSAL 库,并通过调用 UserAgentApplication.loginRedirect() 来登录用户

然后,我调用 acquireTokenPopup 并在访问令牌请求参数中仅传递一个范围:由我的中间层服务定义的范围。执行此操作后,我看到弹出窗口,但随后它消失了(我从未看到任何同意提示)。这成功获取了一个令牌,然后 SPA 将其作为 HTTPS 请求中授权标头上的承载令牌发送到中间层。

然后,中间层尝试通过调用具有如下属性的 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";
Run Code Online (Sandbox Code Playgroud)

它还具有发送的客户端机密,该机密在中间层的 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"}
Run Code Online (Sandbox Code Playgroud)

我看到一些关于需要同意以及我应该如何发送交互式授权请求的内容 - 但我不确定如何做到这一点。事实上,当我最初调用 acquireTokenPopup (而不是 acquireTokenSilent)时,我认为我正在这样做。

如果在具有中间层定义范围的 SPA 客户端中调用 acquireTokenPopup 不是发送交互式授权请求的正确方法,那么什么是?

可能有用的信息:

  • 我的 SPA 客户端应用程序的 ID 列在中间层 AAD 注册门户的“授权客户端应用程序”部分以及清单的“knownClientApplications”部分中。

谢谢!

Roh*_*gal 9

首先,您在所描述的场景中使用代表流程看起来不错。

对于管理员同意部分(为了克服 AADSTS65001 错误),您可以尝试通过以下两种方式之一明确同意:

  • 使用 Azure 门户(适用于单租户应用程序)

    转到 Azure 门户 > Azure AD > 应用程序注册 > 应用程序注册 > API 权限在此输入图像描述然后单击“授予 [您的 AD] 管理员同意”按钮。

    在此输入图像描述

  • 使用管理员同意端点(适用于单租户或多租户应用程序)

    有关 Microsoft Docs 的更多信息,请参见此处 -向目录管理员请求权限

    GET https://login.microsoftonline.com/{tenant}/adminconsent?
    client_id=6731de76-14a6-49ae-97bc-6eba6914391e
    &state=12345
    &redirect_uri=http://localhost/myapp/permissions
    
    Run Code Online (Sandbox Code Playgroud)

    这里唯一的强制参数是client_id. 您可以跳过提供其他参数,并且同意仍然有效。

附带说明一下,您提到的部分knownClientApplications可以帮助解决更高级的场景,即您尝试在一次交互中合并多个应用程序的同意。就像同一个逻辑应用程序的多个层一样。如果这就是您想要实现的目标,那么您实际上不需要单独同意中间层 API。在这种情况下,您仍然可以使用方法 2 作为管理员同意端点。

  • 谢谢。我没有权限为租户的用户提供管理员同意,但我让组织这样做。FWIW,似乎有关发送交互式请求的错误消息在这里具有误导性,因为事实证明我的租户被配置为不允许用户同意(_只有_管理员可以这样做),因此没有任何交互式请求可以解决此问题。 (2认同)