【问题标题】:Seeing combined scopes for 2 different APIs within access token在访问令牌中查看 2 个不同 API 的组合范围
【发布时间】:2018-03-28 12:08:29
【问题描述】:

我们有一个 AAD 应用程序,直到最近才需要 MS Graph API 权限。现在它需要 MS Graph API 和 AAD API 权限。应用程序有一个过程来确定用户何时需要重新同意。在添加 AAD API 权限之前,重新同意过程将通过解析 MS Graph API 访问令牌来确定是否需要重新同意以获取其范围。然后它将这些范围与应用程序中包含的静态列表进行比较。如果任何所需权限不属于访问令牌范围的一部分,则用户将被重定向到同意页面以重新同意。添加 AAD API 权限后,应用程序使用适当的 AAD 资源请求和 AAD API 访问令牌。但是,似乎与这两个 API 相关的范围都包含在 MS Graph 访问令牌和 AAD 访问令牌中。

获取访问令牌的代码:

Notifications = new OpenIdConnectAuthenticationNotifications()
{
    AuthorizationCodeReceived = async (context) =>
    {
        var code = context.Code;

        // retriever caller data from the incoming principal
        string claimClientId = Claim.Value(context.AuthenticationTicket.Identity.Claims, Claim.Type.ClientId);

        string upn = Claim.Value(context.AuthenticationTicket.Identity.Claims, ClaimTypes.Name);
        string officeTenantId = Claim.Value(context.AuthenticationTicket.Identity.Claims, Claim.Type.OfficeTenantId, upn);

        //Obtain MS Graph API Access Token
        Credential = new ClientCredential(ClientId, AppKey);
        var signedInUserId = Claim.Value(context.AuthenticationTicket.Identity.Claims, ClaimTypes.NameIdentifier);
        AuthenticationContext authContext = new AuthenticationContext($"{LoginEndpoint}/{officeTenantId}", new RedisTokenCache(signedInUserId));
        AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), Credential, GraphResourceId);
        //Obtain AAD Graph API Access Token
        AuthenticationResult aadResult = await authContext.AcquireTokenByAuthorizationCodeAsync(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), Credential, AadGraphResourceId);
…

我要回来的范围:

  • 资源 = graph.windows.net,范围 = Directory.AccessAsUser.All Directory.ReadWrite.All Files.ReadWrite.All,Group.ReadWrite.All,profile,User.Read
  • 资源 = graph.microsoft.com,范围 = Directory.AccessAsUser.All,Directory.ReadWrite.All,Files.ReadWrite.All,Group.ReadWrite.All,profile,User.Read

我期待的范围:

  • 资源 = graph.windows.net,范围 = Directory.AccessAsUser.All,User.Read
  • 资源 = graph.microsoft.com,范围 = Directory.ReadWrite.All,Files.ReadWrite.All,Group.ReadWrite.All,profile,User.Read

根据我所看到的,这两个资源似乎都获得了与用户同意的所有 API 关联的范围。这是预期的行为吗?如何获取每个资源的单独范围列表?

以下是 MS Graph Explorer、AAD Graph Explorer 和 JWT 解码器的一些输出:

//Service Principal for my test app
{
    "odata.metadata": "https://graph.windows.net/myorganization/$metadata#directoryObjects/Microsoft.DirectoryServices.ServicePrincipal/@Element",
    "odata.type": "Microsoft.DirectoryServices.ServicePrincipal",
    "objectType": "ServicePrincipal",
    "objectId": "2f9f4cf5-7576-42c9-8f9d-c1c3e6e63b4d",
    "appDisplayName": "My Test App",
}

//Service Principal for MS Graph API
{
    "odata.metadata": "https://graph.windows.net/myorganization/$metadata#directoryObjects/Microsoft.DirectoryServices.ServicePrincipal/@Element",
    "odata.type": "Microsoft.DirectoryServices.ServicePrincipal",
    "objectType": "ServicePrincipal",
    "objectId": "4036b7c7-c9b0-447f-a5d8-18794d0d2a23",
    "appDisplayName": "Microsoft Graph",
    "appId": "00000003-0000-0000-c000-000000000000",
}

//Service Principal for AAD API
{
    "odata.metadata": "https://graph.windows.net/myorganization/$metadata#directoryObjects/Microsoft.DirectoryServices.ServicePrincipal/@Element",
    "odata.type": "Microsoft.DirectoryServices.ServicePrincipal",
    "objectType": "ServicePrincipal",
    "objectId": "aeb2d60b-0681-40f5-abe9-e0e66e793f3e",
    "appDisplayName": "Windows Azure Active Directory",
    "appId": "00000002-0000-0000-c000-000000000000",
}

//oAuth2PermissionGrants for user
{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#oauth2PermissionGrants",
    "value": [
        {
            "clientId": "2f9f4cf5-7576-42c9-8f9d-c1c3e6e63b4d",
            "consentType": "Principal",
            "expiryTime": "2018-03-30T21:31:15.7114922Z",
            "id": "9UyfL3Z1yUKPncHD5uY7TQvWsq6BBvVAq-ng5m55Pz6rJZQ8BUBCT5nGOphIZSeR",
            "principalId": "3c9425ab-4005-4f42-99c6-3a9848652791",
            "resourceId": "aeb2d60b-0681-40f5-abe9-e0e66e793f3e",
            "scope": "User.Read Directory.AccessAsUser.All",
            "startTime": "0001-01-01T00:00:00Z"
        },
        {
            "clientId": "2f9f4cf5-7576-42c9-8f9d-c1c3e6e63b4d",
            "consentType": "Principal",
            "expiryTime": "2018-03-30T21:31:15.7114922Z",
            "id": "9UyfL3Z1yUKPncHD5uY7Tce3NkCwyX9EpdgYeU0NKiOrJZQ8BUBCT5nGOphIZSeR",
            "principalId": "3c9425ab-4005-4f42-99c6-3a9848652791",
            "resourceId": "4036b7c7-c9b0-447f-a5d8-18794d0d2a23",
            "scope": "profile Files.ReadWrite.All Directory.ReadWrite.All Group.ReadWrite.All User.Read",
            "startTime": "0001-01-01T00:00:00Z"
        }
    ]
}

//Access tokens granted to user after sign-in
{
    "aud": "https://graph.windows.net",
    "scp": "Directory.AccessAsUser.All Directory.ReadWrite.All Files.ReadWrite.All Group.ReadWrite.All profile User.Read",
}
{
    "aud": "https://graph.microsoft.com",
    "scp": "Directory.AccessAsUser.All Directory.ReadWrite.All Files.ReadWrite.All Group.ReadWrite.All profile User.Read",
}

【问题讨论】:

    标签: c# owin microsoft-graph-api


    【解决方案1】:

    当您请求您的范围时,您需要在范围前加上资源标识符。

    对于 Azure AD Graph API,这是 https://graph.windows.net/,对于 Microsoft Graph API,它是 https://graph.microsoft.com/。您完成的范围请求应该类似于

    &scope=https%3A%2F%2Fgraph.windows.net%2FDirectory.AccessAsUser.All+https%3A%2F%2Fgraph.windows.net%2FUser.Read+https%3A%2F%2Fgraph.microsoft.com%2FDirectory.ReadWrite.All+https%3A%2F%2Fgraph.microsoft.com%2FFiles.ReadWrite.All+https%3A%2F%2Fgraph.microsoft.com%2FGroup.ReadWrite.All+https%3A%2F%2Fgraph.microsoft.com%2Fprofile+https%3A%2F%2Fgraph.microsoft.com%2FUser.Read
    

    【讨论】:

    • 我删除了 https... 因为该网站显示我无法发布链接。我找回的访问令牌可以工作,但我对其中包含的范围感到困惑。范围列表是错误的。不确定您说“请求”时的意思有两个不同的访问令牌,每个访问令牌都通过具有正确资源的请求获得,一个用于 MS Graph,另一个用于 AAD。当我解码 JWT 时,我看到每个令牌的 aud 都是正确的,但 scp 声明包含 MS Graph 和 AAD 的声明列表。
    • 当您传入scope 查询参数时,您“请求”用户授权您的应用程序使用一组范围。当您第一次将用户定向到 login.microsoftonline.com... 时会传入这些范围
    • 登录时通过 OWIN 请求的范围看起来像某种令牌,'...&scope=openid+profile&...' 我希望访问令牌从与应用程序的 servicePrincipal 关联的 Oauth2PermissionGrants。因此,即使用户在登录期间同意每个资源的所有权限,每个资源的关联范围也会在相应的访问令牌中返回。我没看到。
    • 在上面发布了 MS Graph 和 AAD 浏览器的一些输出。看起来一切都已正确创建,但访问令牌解码显示访问令牌包含范围的混合?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    • 2020-10-05
    • 2016-09-18
    • 1970-01-01
    • 2023-03-23
    • 2021-08-26
    • 1970-01-01
    相关资源
    最近更新 更多