2017-10-16 4 views
1

Nous avons une application AAD qui nécessitait uniquement les autorisations de l'API MS Graph jusqu'à récemment. Maintenant, il nécessite à la fois l'API MS Graph et les autorisations API AAD. L'application a un processus pour déterminer quand l'utilisateur a besoin de re-consentir. Avant l'ajout de l'autorisation de l'API AAD, le processus de renouvellement de consentement déterminait si le consentement était nécessaire en analysant le jeton d'accès de l'API MS Graph pour obtenir ses étendues. Il compare ensuite ces étendues à une liste statique contenue dans l'application. Si l'une des autorisations requises ne fait pas partie des portées du jeton d'accès, l'utilisateur a été redirigé vers la page de consentement afin de donner son consentement à nouveau. Avec l'ajout des autorisations API AAD, les demandes d'application et le jeton d'accès API AAD utilisent la ressource AAD appropriée. Cependant, il semble que les portées associées aux deux API sont contenues à la fois dans le jeton d'accès MS Graph et dans le jeton d'accès AAD.Affichage d'étendues combinées pour 2 API différentes dans le jeton d'accès

code pour obtenir les jetons d'accès:

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); 
… 

Scopes Je reviens:

  • Resource = graph.windows.net, Scopes = Directory.AccessAsUser.All Directory.ReadWrite. Tous les fichiers.ReadWrite.All, Group.ReadWrite.All, profil, User.Read
  • Ressource = graph.microsoft.com, Scopes = Répertoire.AccessAsUser.All, Directory.ReadWrite.All, Files.ReadWrite.All, Groupe .ReadWrite.All, profile, User.Lire

Scopes J'attends:

  • Resource = graph.windows.net, Scopes = Directory.AccessAsUser.All, User.Read
  • Resource = graph.microsoft.com, Scopes = Répertoire .ReadWrite.All, Files.ReadWrite.All, Group.ReadWrite.All, profil, User.Read

d'après ce que je vois, il ressemble à la fois les ressources obtenir les champs d'application associés à toutes les API l'utilisateur consentit à. Est-ce que ce comportement est attendu? Comment puis-je obtenir des listes d'étendues distinctes pour chaque ressource?

Voici quelques sortie de MS Graph Explorer, DAA Graph Explorer et décodeur 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", 
} 

Répondre

0

Lorsque vous demandez à vos champs que vous aurez envie de préfixer les champs avec l'identifiant de ressource. Pour l'API Azure AD Graph, il s'agit de https://graph.windows.net/ et pour API Microsoft Graph de https://graph.microsoft.com/. Votre demande de portée complète devrait ressembler à quelque chose comme

&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 
+0

J'ai supprimé le https ... parce que ce site Web a indiqué que je ne pouvais pas poster les liens. Les jetons d'accès que je récupère fonctionnent mais je suis confus quant aux portées qu'ils contiennent. La liste des portées est erronée. Vous ne savez pas ce que vous voulez dire quand vous dites "demande" Il y a deux différents jetons d'accès chacun gotton par demande avec la ressource correcte, un pour MS Graph l'autre pour AAD. Lorsque je décode le JWT, je vois que l'aud est correct pour chaque jeton mais la réclamation scp contient une liste de réclamations pour MS Graph et AAD. –

+0

Lorsque vous passez le paramètre de requête 'scope', vous« demandez »à l'utilisateur d'autoriser votre application pour un ensemble d'étendues. Ces portées sont transmises lorsque vous redirigez l'utilisateur vers http: //login.microsoftonline.com/... –

+0

La portée de la requête via OWIN sur la connexion ressemble à une sorte de jeton, '... & scope = openid + profil & ...«Je m'attendrais à ce que le jeton d'accès obtienne ses étendues des Oauth2PermissionGrants associés au servicePrincipal de l'application. Ainsi, même si l'utilisateur consent à toutes les autorisations de chaque ressource lors de la connexion, les étendues associées à chaque ressource seront renvoyées dans les jetons d'accès respectifs. Je ne vois pas ça. –