Alessandro Bari
Alessandro Bari

Reputation: 13

401 Unauthorized when try to call office 365 API with an obtained access token

I'm using Java to create a simple daemon or service app (not Web app) to call an Office 365 Calendar API. I've followed this guide Call Microsoft Graph in a service or daemon app, but when I try to call the API with the access token, I obtain a 401 error. I've registered the app to azure portal with all the Graph authorizations and I've made the certificate, following the Step 1 of this guide: Get a certificate or create a self-signed certificate. Here is my code for the access token request:`

    String accessToken="";
    String token_endpoint = "https://login.windows.net/<mytenant>/oauth2/token";
    String grant_type = "client_credentials";
    String client_secret = <mysecret>;
    String resource = "https://graph.microsoft.com";
    String client_id = <myclient>;

    CloseableHttpClient httpclient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(token_endpoint);
    List<NameValuePair> parameters = new ArrayList<>();
    parameters.add(new BasicNameValuePair("grant_type", grant_type));
    parameters.add(new BasicNameValuePair("client_id", client_id));
    parameters.add(new BasicNameValuePair("client_secret", client_secret));
    parameters.add(new BasicNameValuePair("resource", resource));
    httpPost.setEntity(new UrlEncodedFormEntity(parameters));
    httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");

    try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
        System.out.println(response.getStatusLine());
        HttpEntity entity = response.getEntity();

        //parsing
        JSONParser parser = new JSONParser();
        Scanner httpResponseScanner = new Scanner(entity.getContent());
        String jsonString = httpResponseScanner.nextLine();
        //System.out.println(jsonString);
        JSONObject json = (JSONObject) parser.parse(jsonString);
        accessToken = json.get("access_token").toString();

        EntityUtils.consume(entity);
    }
    return accessToken;`

And here is my API call code:`

     String apiURL = "https://outlook.office.com/api/v2.0/me/calendars";
     CloseableHttpClient httpclient = HttpClients.createDefault();
     HttpGet httpGet = new HttpGet(apiURL);
     httpGet.addHeader("Accept", "application/json");
     httpGet.addHeader("Authorization", "Bearer " + accessToken);

     try (CloseableHttpResponse response = httpclient.execute(httpGet)) {
         System.out.println(response.getStatusLine());
         HttpEntity entity = response.getEntity();
         EntityUtils.consume(entity);
     }`

I've already tested my access token to jwt.io with invalid signature response, so I think there is something wrong in my token request. Someone can help me?

Upvotes: 1

Views: 3201

Answers (1)

Nan Yu
Nan Yu

Reputation: 27578

From your code , you are acquiring token for resource :https://graph.microsoft.com , but in api calls with that token , you are calling the outlook mail rest api (https://outlook.office.com/) . If you want to call microsoft graph api (https://graph.microsoft.com ) , you should check the microsoft graph api get calendars .

The second problem is you are using client credential flow (app's identity) , you can't use user identity (/me) because there is no user information includes in access token . With microsoft graph api , you could use GET /users/{id | userPrincipalName}/calendars

Upvotes: 0

Related Questions