C# 令牌检索期间需要管理员同意的Web应用程序

C# 令牌检索期间需要管理员同意的Web应用程序,c#,azure-active-directory,microsoft-graph-api,msal,C#,Azure Active Directory,Microsoft Graph Api,Msal,我的目标是绕过登录屏幕,使用Azure AD作为身份提供者 鉴于我已经使用Azure AD用户登录,我希望使用静默流检索授权令牌,并将其用于受保护的资源 我有一个在ASP.NET MVC 5上运行的web应用程序和一个由Azure AD管理和支持的用户,即联邦用户。作为起点,我遵循了本文中的步骤: 如果我理解正确,我应该能够使用静默身份验证,因为我的用户是联合的,并且我的应用程序注册为公共应用程序 在Azure AD中,我的应用使用以下属性注册: 从url看,代码很简单 var app = Pu

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

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

我有一个在ASP.NET MVC 5上运行的web应用程序和一个由Azure AD管理和支持的用户,即联邦用户。作为起点,我遵循了本文中的步骤:

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

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

从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=&nonce=1234&resource=User.Read&prompt=consent

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

所以它没有显示任何同意屏幕,只是让我选择我想要使用的Microsoft帐户。这是因为管理员已授予用户的同意。读取权限吗


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

有了委托权限,每个用户都需要同意应用程序。如果您不需要该要求,租户管理员可以同意Azure门户的所有用户

由于集成Windows身份验证是静默流,因此应用程序的用户必须事先同意使用该应用程序,或者租户管理员必须事先同意租户中的所有用户使用该应用程序

您可以使用prompt=approve强制通过URL请求,URL如下所示:

https://login.microsoftonline.com/<tenant-id>/oauth2/authorize?client_id=<client id>&response_type=code&redirect_uri=<Your-Redirect-URI-Https-Encoded>&nonce=1234&resource=<your-resource-Https-encoded>&prompt=consent
如果需要,请使用$prompt=admin_PROPERT。需要使用admin帐户登录


有关修复错误AADSTS65001的更多详细信息,请参阅此。

您混合了两种不同的AAD OAuth机制,即v1和v2端点。v1端点使用资源https://graph.microsoft.com 而v2端点使用作用域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

用户或管理员是否同意所需权限?您是否希望用户使用其联合Azure AD用户帐户登录到您的web应用?或者您是否希望代表已使用集成Windows Auth登录到web应用的用户获取访问令牌?@PhilippeSignoret我正在尝试使用联合Azure AD帐户登录到我的web应用,因为我已使用此帐户登录。我已尝试强制用户同意。屏幕上显示了我可以选择Microsoft帐户的屏幕,之后我被重定向到我的网站,AcquireTokenByIntegratedWindowsAuth的行为没有改变。我希望在得到同意的情况下看到屏幕,但事实并非如此。有什么想法吗?将resource=User.Read更改为resource=https://graph.microsoft.com 然后重试。通过更改为资源=https://graph.microsoft.com 我确实得到了弹出窗口,但单击“接受”后,对AcquireTokenByIntegratedWindowsAuth的调用仍会引发一个请求用户同意的异常。如果您正在使用.NET core或不想执行AcquireTokenInteractive,则可能需要建议用户导航https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response\u type=code&scope=user.read。请参阅本文中的内容。据我所知,AcquireTokenInteractive在web应用程序中不起作用。我收到这个错误,并且据我所知,一个web应用没有UI线程,这就是这个方法所需要的。错误是无法实例化ActiveX控件,因为当前线程不在单线程单元mvc控制器中。因为我已经登录了,所以整个想法是能够以静默的方式获取用户/凭证,但这似乎在web应用程序中不起作用?嗨,Marc。当使用此url时,它会将我重定向到我所在组织的Microsoft登录屏幕,然后我登录,我会被重定向到我的应用程序的url,该url现在有一个代码查询字符串参数填充在url \?code=xxxxxx中。我的网站已启用windows身份验证,但对AcquireTokenByIntegratedWindowsAuth的调用仍会引发相同的异常,表示我无法验证
未经授权的用户同意。你知道在网络应用中还需要哪种设置吗?你能试着解码你得到的令牌吗?请确保它包含正确的租户和作用域。您还可以尝试将/common/替换为/{tenant id}/。上一次我尝试这样做时,我相信我总是使用租户id将用户重定向到auth页面。第一次它请求同意,但从那时起,它会自动重定向回。这就是说,这是几年前的事了,所以我可能忘记了一个步骤。嗨,马克,我确实把它改成了租户id,因为我只想让我的组织的帐户能够登录。一切正常,我现在可以进入流程的另一部分。谢谢你的帮助。