首页 > 解决方案 > 在令牌检索期间需要管理员同意的 Web 应用程序

问题描述

我的目标是绕过登录屏幕并使用 Azure AD 作为身份提供者。

鉴于我已经使用我的 Azure AD 用户登录,我想使用静默流检索授权令牌并将其用于受保护的资源。

我有一个在 ASP.NET MVC 5 上运行的 Web 应用程序和一个由 Azure AD(即联合用户)管理和支持的用户。作为起点,我已按照本文中的步骤进行操作:集成 Windows 身份验证

如果我理解正确,我应该能够使用静默身份验证,因为我的用户是联合的并且我的应用程序已注册为公共应用程序。

在 Azure AD 中,我的应用注册了以下属性:

id 和访问令牌

公开申请

权限

代码很简单,来自 url。

var app = PublicClientApplicationBuilder.CreateWithApplicationOptions(
        new PublicClientApplicationOptions()
        {
            ClientId = "<clientId>",
            TenantId = "<tenantId>",
            LogLevel = LogLevel.Verbose,
            AzureCloudInstance = AzureCloudInstance.AzurePublic,
        })
    .Build();

var scopes = new [] { "User.Read" };

var result = await app.AcquireTokenByIntegratedWindowsAuth(scopes)
    .WithUsername("<username>")
    .ExecuteAsync();

获取令牌的调用会抛出以下异常:

“AADSTS65001:用户或管理员未同意使用 ID 为‘xxx’、名为‘xxx’的应用程序。为此用户和资源发送交互式授权请求”

根据文档User.Read不需要管理员同意。那么我在这里做错了什么?

编辑:我构建了一个提示用户同意的 URL:https://login.microsoftonline.com/tenantId/oauth2/authorize?client_id=clientId&response_type=code&redirect_uri=<myApp>&nonce=1234&resource=User.Read&prompt=consent

它把我带到我需要选择我的帐户的屏幕,然后,我被重定向到我的应用程序,在那里我再次遇到相同的异常。

所以它不会显示任何同意屏幕,只是要求我选择我想使用的 Microsoft 帐户。这是因为User.Read管理员已经同意了吗?

但为什么我仍然收到错误?在这一点上我有点困惑。

标签: c#azure-active-directorymicrosoft-graph-apimsal

解决方案


您正在混合两种不同的 AAD OAuth 机制(又名 v1 和 v2 端点)。v1 端点使用 Resources ( https://graph.microsoft.com),而 v2 端点使用 Scopes ( user.read)。因此,当您请求时resource=User.Read,您将传递给它一个无效的资源名称。

我建议使用具有以下 URI 原型的 v2 端点(换行符以提高可读性):

https://login.microsoftonline.com/common/oauth2/v2.0/authorize
?client_id={clientId}
&response_type=id_token
&redirect_uri={your_app}
&response_mode=fragment
&scope=user.read

推荐阅读