web-dev-qa-db-fra.com

Échec de validation du jeton de l'API Microsoft Graph

J'utiliserais l'API Microsoft Graph dans mon Angular.

Je fais d'abord la connexion en utilisant bibliothèque msal Lorsque j'essaye de me connecter avec mon profil, j'obtiens cette erreur

J'ai configuré mon application comme mentionnée dans l'officiel exemple git

MsalModule.forRoot({
  clientID: "Tenant ID",
  authority: "https://login.microsoftonline.com/common/",
  redirectUri: "http://localhost:4200/",
  validateAuthority : true,
  popUp: true
}),

L'authentification fonctionne et j'obtiens le jeton.

Ensuite, lorsque je suis sur la page d'accueil, je fais une deuxième demande à l'API Microsoft Graph pour obtenir des informations utilisateur à l'aide de ce jeton.

getProfile() {
  let header= new Headers();
  let tokenid= sessionStorage.getItem('msal.idtoken'); 
  header.set('Authorization', 'Bearer ' + tokenid)
  let url ="https://graph.Microsoft.com/v1.0/me/"
  return this.http.get(url,{headers:header});
}

}

J'obtiens une erreur 401 non autorisée avec une réponse:

{
  "error": {
    "code": "InvalidAuthenticationToken",
    "message": "Access token validation failure.",
    "innerError": {
      "request-id": "xxxxxx",
      "date": "2018-10-09T22:58:41"
    }
  }
}

Je ne sais pas pourquoi MG API n'accepte pas mon jeton, est-ce que j'utilise une mauvaise URL d'autorisation?

[~ # ~] mise à jour [~ # ~] : J'ai compris qu'en fait, j'obtiens id_token qui est différent du jeton d'accès. Comment puis-je obtenir un jeton d'accès à partir de la bibliothèque MSAL pour effectuer des appels à l'API MS GRAPH?:

6
infodev

Le problème est que vous utilisez l'id_token au lieu du jeton d'accès:

let tokenid= sessionStorage.getItem('msal.idtoken');

devient quelque chose comme:

let tokenid= sessionStorage.getItem('msal.token'); // or msal.accesstoken

Mise à jour (selon le commentaire de Phillipe)

Vous devez sélectionner les étendues que vous souhaitez cibler dans votre application. Ainsi, il semble que vous souhaitiez le profil utilisateur, vous souhaiterez donc ajouter la propriété consentScopes pour spécifier les étendues que votre application utilisera:

MsalModule.forRoot({
  clientID: "Tenant ID",
  authority: "https://login.microsoftonline.com/common/",
  redirectUri: "http://localhost:4200/",
  validateAuthority : true,
  popUp: true,
  consentScopes: ["user.read"]
}),
2
Michael Mainer

Selon le même exemple vous pouvez également attacher un HttpInterceptor qui attachera automatiquement le jeton d'accès à chaque (externe) Appel HTTP.

En lisant la documentation, j'ai trouvé les informations suivantes.

consentScopes: Permet au client d'exprimer les portées souhaitées qui doivent être acceptées. Les étendues peuvent provenir de plusieurs ressources/points de terminaison. Passer la portée ici ne fera que le consentir et aucun jeton d'accès ne sera acquis jusqu'à ce que le client appelle réellement l'API. Ceci est facultatif si vous utilisez MSAL pour la seule connexion (authentification).

Cela suggère que l'utilisation du HttpInterceptor non seulement attache le jeton d'accès, mais le récupère également. Le jeton que vous voyez n'est probablement qu'un jeton pour votre application, mais n'est pas un jeton valide pour l'API Graph.

En interne, il utilise getCachedTokenInternal(scopes: Array<string>, user: User) pour obtenir un nouveau jeton d'accès pour des étendues spécifiques code trouvé ici . Je ne sais pas si vous pouvez également utiliser cette méthode pour obtenir un nouveau jeton pour cette ressource. J'utiliserais juste l'intercepteur.

Vous pouvez essayer de copier le jeton d'accès et voir à quoi il ressemble sur jwt.ms (une visionneuse de jetons JWT fournie par Microsoft) ou jwt.io .

Tous les jetons valides pour Graph doivent avoir le Public de https://graph.Microsoft.com, donc si vous inspectez le jeton (en jwt.ms), il devrait au moins avoir cette valeur.

"aud": "https://graph.Microsoft.com",
2
Stephan