设置提示=同意后,Azure Active Directory 需要管理员批准

Azure Active Directory needs Admin Approval after setting prompt =consent

在我在 Azure Active Directory 中的应用程序中,我已经添加了管理员同意所需的图表权限之一 API,比方说 Group.Read.All。我点击了 Grant Admin Consent for ...。如果我使用查询参数 prompt=consent 作为用户点击 /authorize 端点,我将获得需要管理员批准的视图。如果我在没有任何 prompt 参数的情况下到达端点,一切正常 - 我能够获得具有适当范围的令牌。在我读到的文档中,prompt 参数仅决定同意的可见性。为什么会这样?

prompt=consent triggers the OAuth consent dialog after the user signs in, asking the user to grant permissions to the app.

访问应用程序的个人需要至少一项超出其权限范围的权限。

管理员将看到显示权限的相同提示,并将看到对传统同意提示的额外控制,这将允许他们代表整个租户同意。

用户将被阻止授予该应用程序的许可,并且他们将被告知向他们的管理员请求访问该应用程序。

更多细节,你可以参考这个article

关于prompt=consentOpenID Connect says

The Authorization Server SHOULD prompt the End-User for consent before returning information to the Client. If it cannot obtain consent, it MUST return an error, typically consent_required.

在 Microsoft Identity 平台中,这意味着最终用户将需要提供同意,即使用户先前已授予同意或(在工作或学校帐户,由代表用户的管理员创建)。

如果用户无权同意所请求的权限(例如,因为用户同意被禁用或限制),使用 prompt=consent 将始终导致用户被硬阻止。

在大多数情况下,使用 prompt=consent 不是 最佳方法。通常会考虑三种情况 prompt=consent

  1. 您已更改所需的权限。所需的权限已更改(例如,已添加或删除权限),用户需要同意新的权限集。
  2. 您想通知用户。应用开发者希望确保用户了解应用将被授权行使哪些权限(即使管理员已经代表相关用户表示同意)。
  3. 您需要征得用户本人的同意,而不是管理员。应用程序开发人员希望确保最终用户自己提供同意,而不管管理员之前可能已经授权了什么。

如果您更改了所需的权限

动态定义请求的权限时

the v2.0 endpoint, the scope parameter can be used to dynamically 请求委派权限列表。例如,要请求 https://api.example.com 标识的 API 的 readexport 委托权限:

scope=openid https://api.example.com/read

Azure AD 将确保已授予所有请求的权限,并尝试提示同意尚未授予的任何权限(且仅针对那些)。如果请求的权限都已被授予,则颁发的令牌将包括所有授予的权限(即使它们没有被特别请求)。

一般来说,在使用 v2.0 端点的增量同意功能时,prompt=consent 应该而不是。如果需要,Azure AD 将负责提示增量同意。

当静态定义请求的权限时

应用程序还可以仅识别它为其请求访问令牌的资源(即 API),具体权限是为应用程序静态定义的。使用 v2.0 端点,这是在 scope 参数中完成的,利用 the special .default permission value:

scope=openid https://api.example.com/.default

the v1.0 endpoint中,这是使用resource参数实现的:

resource=https://api.example.com

所需权限的列表在应用程序注册的静态列表中配置。在 Azure 门户中,此列表位于 Azure AD > 应用注册 > API 权限中的 已配置权限 下。在下层Application entity in Microsoft Graph (and in the app manifest),这是存放在requiredResourceAccess属性.

收到此类请求(在 v1 或 v2 端点上)时,Azure AD 将检查已为请求的资源授予了哪些权限:

  1. 如果没有已为请求的资源授予委派权限如果使用prompt=consent,Azure AD将尝试从静态定义的列表中提示所有必需的权限。这将包括其他 API 的权限(如果已配置)。
  2. 如果已为请求的资源授予 any 委派权限,Azure AD 将颁发具有所有授予权限的令牌。响应 的scopes 参数 将包含访问令牌中包含的权限列表。

依赖于静态定义所需权限的应用程序(即 v2 上的 /.default 或 v1 上的 resource)应该 使用 prompt=consent每个登录请求。相反,应用程序应该:

  1. 执行签到 没有 prompt=consent.
  2. 检查响应scope参数:
    • 如果列出了所需的权限,则无需进一步操作。
    • 如果不是(例如,如果在用户最初同意该应用程序后将新权限添加到所需权限列表),只有在 用户才应该被再次送回, 这次 prompt=consent.

此策略可确保用户在管理员代表他们同意(例如,因为他们无权自行同意)时可以登录应用程序,并且只强制显示同意提示(或升级到管理员代表他们同意)在配置新权限时。

如果要通知用户

如果目标只是通知用户应用程序已被授权行使哪些权限(或者由用户以前,或由管理员代表用户)。

相反,应用程序可以使用令牌响应的 scope 参数来构建所需的中断体验(例如,在用户被重定向回应用程序并且令牌已被检索之后,但在继续之前), 通知用户它被授予了哪些权限。

如果您需要用户同意,而不是管理员同意

可能存在非常特殊的情况,当应用程序要求用户同意所请求的权限,并希望接受授予的同意由管理员代表用户。

在这种情况下,可以在所有登录中使用 prompt=consent,但有一些重要的注意事项需要考虑:

  • 在许多组织中,user consent is disabled 或受到限制。如果用户无权同意为您的应用配置的权限,他们将无法使用您的应用。
  • 每次登录都会提示用户同意,即使用户自己之前已经同意。
  • 因为这是一个查询参数,知识渊博的用户可以很容易地在请求发出之前拦截它,并删除 prompt=consent(如果之前已经同意,他们将不会被提示同意) .

在这种情况下,应用在 用户登录后 实施单独的同意授予体验可能更好(类似于描述的 "inform" 场景较早前),将应用的额外同意要求与 Microsoft 标识平台提供的同意体验分开。