在访问令牌

时间:2017-10-16 21:22:46

标签: c# owin microsoft-graph

我们有一个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);
…

范围我要回来了:

  • Resource = graph.windows.net,Scopes = Directory.AccessAsUser.All Directory.ReadWrite.All Files.ReadWrite.All,Group.ReadWrite.All,profile,User.Read
  • Resource = graph.microsoft.com,Scopes = Directory.AccessAsUser.All,Directory.ReadWrite.All,Files.ReadWrite.All,Group.ReadWrite.All,profile,User.Read

我期待的范围:

  • Resource = graph.windows.net,Scopes = Directory.AccessAsUser.All,User.Read
  • Resource = graph.microsoft.com,Scopes = Directory.ReadWrite.All,Files.ReadWrite.All,Group.ReadWrite.All,profile,User.Read

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

这是MS Graph Explorer,AAD Graph Explorer和JWT decoder的一些输出:

//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",
}

1 个答案:

答案 0 :(得分:0)

当您请求范围时,您希望在范围前添加资源标识符。

对于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