如何查明我的应用是否已获得管理员同意?

Eko*_*val 4 azure-active-directory microsoft-graph-api

我正在使用 Microsoft Graph 中的安全 API 编写一个 Web 应用程序,并且正在使用 Azure AD 进行身份验证,但访问 API 所需的权限需要使用我的应用程序的每个租户的管理员同意。

\n\n

如何检查租户管理员是否同意我的应用程序?这样我就知道是将用户发送到常规登录流程还是管理员同意流程。

\n\n

是否可以对 Azure AD 进行 REST 调用以获取此信息?我\xe2\x80\x99已经尝试使用oAuth2PermissionGrant ,但这似乎只适用于对象ID,而且我只有我的应用程序/客户端ID。

\n\n

编辑

\n\n

我对我的应用程序中需要哪些范围感到困惑,但事实证明,当我添加管理员时,仅委派权限,例如SecurityEvents.Read.All应用程序注册门户SecurityEvents.ReadWrite.All,并且仅使用User.Read我的应用程序中的权限来请求用户的基本信息。请求访问令牌时有两种不同的结果;

\n\n
    \n
  • 如果管理员没有给予我的应用程序同意,那么访问令牌将只包含User.Read范围。
  • \n
  • 如果管理员已同意,则访问令牌将包含User.ReadSecurityEvents.Read.AllSecurityEvents.ReadWrite.All委托范围。即使我的应用程序只请求User.Read.
  • \n
\n\n

我发现我可以使用它来通过检查访问令牌范围来确定管理员是否同意我的应用程序。如果它包含SecurityEvents.Read.All, 或SecurityEvents.ReadWrite.All那么用户可以继续在应用程序中。但如果这些委派的权限不在范围内,那么我可以提示https://login.microsoftonline.com/common/adminconsent?client_id=<APP ID>&state=12345&redirect_uri=http://localhost/myapp/permissions管理员同意流程请求将权限添加到租户。

\n\n

谢谢@marc-lafleur,我正在使用管理员帐户来玩oAuth2PermissionGrantGraph Explorer,直到你指出为止,我没有发现先有鸡还是先有蛋的情况。

\n

Mar*_*eur 5

当您执行管理员同意时,它会将以下查询参数附加到您的redirect_uri

tenant={id}&admin_consent={bool}
Run Code Online (Sandbox Code Playgroud)
  • tenant- 这是刚刚执行管理员同意的租户的全局唯一 ID。
  • admin_consent- 这是一个布尔值,指示您的管理员同意是被授予 ( true) 还是被拒绝 ( false)。

通常您会捕获并存储这些值。当您需要确定是否需要请求管理员同意时,您可以从应用程序中查找它们。

存储日期/时间也是一个好主意。如果您的注册范围自最初同意以来发生了变化,这将允许您重新请求同意。

至于图形端点,这对您没有多大帮助。由于您需要拥有有效的令牌才能调用 Graph,并且您需要管理员同意才能获得该令牌,因此将其锁定在 Graph 本身中将出现鸡与蛋的情况;在他们同意之前,你无法检查他们是否同意。

也就是说,您可以使用servicePrincipaloAuth2PermissionGrant资源来确定同意:

  1. 首先,您需要使用idservicePrinipalappId.

    /beta/servicePrincipals?$filter=appId eq '{appId}'
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从对上一个查询的响应中,获取id并使用它来检索oAuth2PermissionGrants您的应用程序的 。

    /beta/oauth2PermissionGrants?$filter=resourceId eq '{servicePrincipal.id}'
    
    Run Code Online (Sandbox Code Playgroud)

请注意,这些是/beta端点,不适合生产使用。

  • 如果您想要“生产可用”端点,那么这就是 Azure AD Graph API 仍然是推荐的一种场景。作为附加细节,`oauth2PermissionGrant` 将具有用于管理员同意的 `"consentType": "AllPrincipals"` 和 `"principalId": null`。 (2认同)