Microsoft Graph 401 Unauthorized with access token

2019-08-11 00:54发布

问题:

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.

回答1:

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.



回答2:

The reason for this is the application must also have support for the permissions requested. Case in point is an application isn't allowed to list managed devices as shown in the Prerequisites page in this page List managedDevices permissions