Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microsoft Graph 401 Unauthorized with access token

Unable to get data from the the Microsoft Graph API.

private String getUserNamesFromGraph() throws Exception {
      String bearerToken = "Bearer "+getAccessToken();
      String url = "https://graph.microsoft.com/v1.0/users";
      String returnData = null;

      try {
        URL apiURL = new URL(url);
        URLConnection con = apiURL.openConnection();
        con.setRequestProperty("Authorization", bearerToken);
        con.setRequestProperty("Content-Type", "application/json");

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

        returnData = response.toString();
        System.out.println(returnData);

      } catch(Exception e) {
        System.out.println(e);
      }

      return returnData;
  }

private String getAccessToken() throws Exception {
    String url = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        // header
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", "eTarget API");
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

        String urlParameters = "client_id=*** 
APPLICATION ID FROM APPLICATION REGISTRATION PORTAL ***&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=*** 
APPLICATION SECRET FROM APPLICATION REGISTRATION PORTAL ***&grant_type=client_credentials";
        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(urlParameters);
        wr.flush();
        wr.close();

        int responseCode = con.getResponseCode();
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        //print result
    String returnData = response.toString();
        System.out.println(returnData);

    Map jsonTokenData = new Gson().fromJson(returnData, Map.class);
    String accessToken = (String)jsonTokenData.get("access_token");
    //System.out.println(accessToken);

    return accessToken;
    }
  • The application is registered
  • I have a method getAccessToken() that successfully returns an access token
  • The method getUserNamesFromGraph() however returns a 401 Unauthorized instead of the expected data.

I've gone through the documentation countless times, trying different variations and endpoints but to no avail. Any ideas appreciated.

like image 801
logic-unit Avatar asked Dec 18 '17 14:12

logic-unit


People also ask

How do I get an access token for Microsoft Graph API?

To get an access token, your app must be registered with the Microsoft identity platform and be authorized by either a user or an administrator to access the Microsoft Graph resources it needs. This article provides an overview of the Microsoft identity platform, access tokens, and how your app can get access tokens.

Is Microsoft Graph deprecated?

Azure Active Directory (Azure AD) Graph is deprecated and will be retired at any time after June 30, 2023, without advance notice, as we announced in September, 2022.

How long does a Microsoft Graph token last?

The default lifetime of the token is 1 hour. From an application's perspective, the validity period of the token is specified by the NotOnOrAfter value of the <conditions …> element in the token.


1 Answers

In order your application to read the users it has to have an explicitly granted User.Read.All application permission. This permission requires admin consent. Here is one link where it is explained how to grant that permission. You must invoke that interactive consent dialog to grant your application the permissions. Otherwise you will still receive Insufficient permissions error.

Then here is the complete list of different Microsoft Graph permissions. In your case - a daemon application without user interaction, you have to look at the application permissions and not **delegated permissions*.

Once you grant appropriate permissions, you will be able to query the users. You do not have to change the scope in your token request. Leave it as it is: https://graph.microsoft.com/.default

Once you make all these changes, you can use https://jwt.ms to check your access token. There you can extract all the claims and check your audience and scope claims to further understand why you get 401 from the Microsoft Graph.

like image 152
astaykov Avatar answered Sep 19 '22 11:09

astaykov