Microsoft Graph 401 未经授权使用访问令牌令牌、未经授权、Microsoft、Graph

2023-09-06 17:10:46 作者:男生帅气昵称

无法从 Microsoft Graph API 获取数据.

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("
Sending '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;
    }

应用程序已注册我有一个方法 getAccessToken() 可以成功返回访问令牌getUserNamesFromGraph() 方法会返回 401 Unauthorized 而不是预期的数据.

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.

推荐答案

为了让您的应用程序能够读取用户,它必须具有明确授予的 User.Read.All 应用程序权限.此权限需要管理员同意.这是一个链接,其中解释了如何授予该权限.您必须调用该交互式同意对话框来授予您的应用程序权限.否则你仍然会收到权限不足的错误.

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.

然后 这里是不同 Microsoft Graph 的完整列表权限.在您的情况下 - 没有用户交互的守护程序应用程序,您必须查看 应用程序权限 而不是 **委派权限*.

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*.

一旦您授予适当的权限,您就可以查询用户.您确实不必更改令牌请求中的范围.保持原样:https://graph.microsoft.com/.default

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

完成所有这些更改后,您可以使用 https://jwt.ms 检查您的访问令牌.在那里,您可以提取所有声明并检查您的受众和范围声明,以进一步了解您从 Microsoft Graph 获得 401 的原因.

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.