sahmad
sahmad

Reputation: 142

InvalidAuthenticationToken calling /me from Microsoft Graph

I am working on a webapp which is hosted on Azure, uses Microsoft Graph API to sign users in using the corporate account email. Now, I'd like to read the sign in user and display him on my view, however, I am getting an InvalidAuthenticationToken error.

AuthHelper.ts:

import { Injectable } from "@angular/core";
import { SvcConsts } from "../service/svcConsts";
import { HttpModule } from "@angular/http";
import { HttpClientModule } from "@angular/common/http";

@Injectable()
export class AuthHelper {
  //function to parse the url query string
  private parseQueryString = function(url) {
    var params = {},
      queryString = url.substring(1),
      regex = /([^&=]+)=([^&]*)/g,
      m;
    while ((m = regex.exec(queryString))) {
      params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
    }
    return params;
  };
  private params = this.parseQueryString(location.hash);
  public access_token: string = null;

  constructor() {
    //check for id_token or access_token in url
    if (this.params["id_token"] != null) this.getAccessToken();
    else if (this.params["access_token"] != null) this.access_token = this.params["access_token"];
  }

  login() {
    //redirect to get id_token
    window.location.href =
      "https://login.microsoftonline.com/" +
      SvcConsts.TENANT_ID +
      "/oauth2/authorize?response_type=id_token&client_id=" +
      SvcConsts.CLIENT_ID +
      "&redirect_uri=" +
      encodeURIComponent(window.location.href) +
      "&state=SomeState&nonce=SomeNonce";
  }

  private getAccessToken() {
    //redirect to get access_token
    window.location.href =
      "https://login.microsoftonline.com/" +
      SvcConsts.TENANT_ID +
      "/oauth2/authorize?response_type=token&client_id=" +
      SvcConsts.CLIENT_ID +
      "&resource=" +
      SvcConsts.GRAPH_RESOURCE +
      "&redirect_uri=" +
      encodeURIComponent(window.location.href) +
      "&prompt=none&state=SomeState&nonce=SomeNonce";
  }
}

SvsConsts.ts:

export class SvcConsts {
  public static CLIENT_ID: string = "my client id here";
  public static TENANT_ID: string = "mydomain.azurewebsites.net";
  public static GRAPH_RESOURCE: string = "https://graph.microsoft.com";
}

HomeComponents.ts:

import { Component } from "@angular/core";
import { Http, Headers } from "@angular/http";
import { AuthHelper } from "../service/AuthHelper";
import { HttpModule } from "@angular/http";
import { HttpClientModule } from "@angular/common/http";

@Component({
  selector: "app-home",
  templateUrl: "./home.component.html"
})
export class HomeComponent {
  private users: any;
  private userPrincipalName: any;

  constructor(http: Http, authHelper: AuthHelper) {
    // Perform REST call into Microsoft Graph for files on GraphAPI
    http
      .get("https://graph.microsoft.com/v1.0/me/", {
        headers: new Headers({
          Authorization: "Bearer { access_token }",
          "Content-Type": "application/json" + authHelper.access_token
        })
      })

      .subscribe(res => {
        // Check the response status before trying to display files

        if (res.status === 200) this.users = res.json().value;
        else alert("An error occurred calling the Microsoft Graph: " + res.status);
      });
  }
}

I am planning to use the userPrincipalName property in Home.Component.html to display, however, I am getting that error. I followed the example provided by Graph GitHub repository and followed documentation on their website. Can you help me with why am I getting this error?

Below is the screen capture of the permissions I have on Azure AD management tool.

AzureAD - Graph permissions

Please help.

Upvotes: 0

Views: 4141

Answers (2)

user10125476
user10125476

Reputation:

Could you give me the request url and the response?
I think you need call the login function in the constructor of the HomeComponent. You may need change the request in this constructor.
And the constructor of the HomeComponent like this:

constructor(http: Http, authHelper: AuthHelper{
console.log(authHelper.access_token);
authHelper.login();
http.get("https://graph.microsoft.com/v1.0/me/", {  
  headers: new Headers({
    "Authorization": "Bearer "+ authHelper.access_token,
     "Content-Type": "application/json" })
})}

Upvotes: 0

user10125476
user10125476

Reputation:

I think you may want to use Microsoft Graph to read and write resources on behalf of a user.I read your code,and I find that there are some mistakes in the login function.
To get an access token,you should redirect user to Azure AD v2.0 /authorize endpoint.The url should like this:

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id={your client_id}&response_type=code 
&redirect_uri={current_url}&response_mode=query
&scope={you want the right }&state=12345


//Please check your parameters,such as response_type,response_mode

When you get authorization from the user,the response will contain the authorization code in the code parameter. Then you can use this code to get an access token for request,the url should be like this:

POST /common/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=user.read%20mail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&client_secret=JqQX2PNo9bpM0uEihUPzyrh    // NOTE: Only required for web apps

Then,the response contains a list of the permissions that the access token is good for in the scope parameter.
I think your url with error,and you can change some parameters for your request.
The reference docs is here:https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_user
If you think my answer is helpful to you, please mark me as answer.Thank you.

Upvotes: 1

Related Questions