管理员同意对话框请求不同的权限,然后请求

问题描述

我正在开发一个托管在 azure 中的 asp.net core .net 5 网络应用,我想为我们的客户提供 SSO 体验。

作为参考,我以 https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/2-WebApp-graph-user/2-3-Multi-Tenant 中的示例为例,其中 AAD 管理员为 AAD 中的所有用户授予应用权限。

该示例使用了此处描述的管理员同意 URL:https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-admin-consent#request-the-permissions-from-a-directory-admin

就我而言,我只想让用户使用他们的公司帐户登录并在登录后阅读他们的电子邮件(没有其他个人资料数据)。所以我认为请求范围“openid”和“email”就足够了。但是我提供什么范围值并不重要,向管理员显示的对话框显示了其他权限请求(看起来像“profile”和“offline_access”(?)):

enter image description here

我像这样构建网址:

var state = Guid.NewGuid().ToString();
var currentUri = UriHelper.BuildAbsolute(
   httpContext.Request.Scheme,httpContext.Request.Host,httpContext.Request.PathBase);

var authorizationRequest = string.Format(
   "https://login.microsoftonline.com/organizations/v2.0/adminconsent?client_id={0}&scope={1}&redirect_uri={2}&state={3}",Uri.EscapeDataString(this.microsoftIdentityOptions.ClientId),Uri.EscapeDataString("openid email"),Uri.EscapeDataString(currentUri + "tenant/processcode"),Uri.EscapeDataString(state));                 

生成的请求如下所示:

enter image description here

有趣的是,如果管理员授予对应用程序的访问权限,并且如果我在 AAD 中检查“企业应用程序”的权限,我会准确地看到我最初想要的“电子邮件”和“openid”权限:

enter image description here

但这让 AAD 管理员感到非常困惑,我真的很想展示一个与我的权限请求相匹配的对话框。

解决方法

默认情况下,如 here 所示,客户端会询问 openid 和配置文件:

        Scope.Add("openid");
        Scope.Add("profile");

这就是为什么您通常会看到对 Clear() 的调用,以清除此默认范围列表,例如:

        options.Scope.Clear();
        options.Scope.Add("openid");
        options.Scope.Add("email");
        options.Scope.Add("myscope");
,

我会解释这两点:

  1. 这是一个已知问题。当您使用 v2.0 端点时,即使您不添加 offline_access 范围,它仍然会显示在管理员同意页面中,并且当前无法删除。 official documentation 也解释了这一点。

此权限当前显示在所有同意页面上,即使对于流也是如此 不提供刷新令牌(例如隐式流)。这 设置解决了客户端可以在隐式中开始的场景 流,然后移动到需要刷新令牌的代码流。

如果您不希望 offline_access 范围出现在初始管理员同意页面中,您可以使用 v1.0 端点。 (但是,1.0 端点只能请求静态权限)

https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id={0}&scope={1}&redirect_uri={2}&state={3}
  1. 如果应用程序使用 OpenID Connect 登录,则它必须请求 openid 范围。 openid 范围默认包括 profile 范围,这是设计使然! openid 的范围在管理员同意页面上解释为:允许用户使用他们的工作或学校帐户登录应用程序,并允许应用程序查看基本的用户个人资料信息。

enter image description here