1

I am using the msgraph-sdk-java to read Emails from Exchange Online with a User scope by using UsernamePasswordCredential authorization. I create a client with lazy initialization and then continue to use it, where I had assumed Client would automatically refresh token when it is necessary. Here is the code for client initialization:

 private GraphServiceClient<Request> client = null;

 private void initializeGraphClient() {

    if (this.client == null) {
        final UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredentialBuilder().clientId(CLIENT_ID)
            .username(user)
            .password(password)
            .build();

        List<String> scopes = Arrays.asList(DEFAULT_SCOPE);
        final TokenCredentialAuthProvider tokenCredentialAuthProvider =
            new TokenCredentialAuthProvider(scopes, usernamePasswordCredential);

        this.client = GraphServiceClient.builder() //
            .authenticationProvider(tokenCredentialAuthProvider) //
            .buildClient();
    }
}

In one of the installations, this works without any problem for a while but fails around 4 Hours later with following problem:

com.microsoft.graph.http.GraphServiceException: Error code: InvalidAuthenticationToken
Error message: Continuous access evaluation resulted in claims challenge with result: InteractionRequired and code: TokenCreatedWithOutdatedPolicies

POST https://graph.microsoft.com/v1.0/me/sendMail
Content-Type : text/plain
SdkVersion : graph-java/v4.0.0
[...]
401 : Unauthorized
[...]
[Some information was truncated for brevity, enable debug logging for more details]

I have seen the latest Version of SDK is 5.x.x, I am using 4.0.0 but I could not see something in change log about refresh problems.

Do I need to refresh token or rebuild client once in a while to avoid such issues?

Also, how can I enable debug logging for Graph SDK Java?

cancomert
  • 51
  • 6
  • not sure about the microsoft api but oauth2 refresh token can expire too (if the outh provider is nice they use jwt tokens that tell you when), in that case you have to refresh periodically to get a new pair of access and refresh tokens. `TokenCreatedWithOutdatedPolicies` doesn't sound like that though. – zapl Sep 19 '22 at 14:07
  • you have to use OAuth , hope this docs help you to refresh token - https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc – vicky kumar Sep 20 '22 at 07:15
  • Thanks for the reply, we are using microsoft-java-sdk and they are already using the Oauth Flow to login internally in this client implementation. It gets correct tokens. It works sometimes for 4 Hours, sometimes for 1 day without any problem and the Organization says the Token Expiration is around 60 minutes. So refresh is actually working as I understand but once in a while we get into this situation. – cancomert Sep 20 '22 at 15:45

1 Answers1

0

It seems like the refresh flow of the Microsoft Graph Java client has a Problem (at least in the 4.0.0 version). It can not refresh token after 1 Hour, which is the expiration time of the token configured in the Azure profile.

Here is the algorithm to rebuild client:

  1. Check if a client is created already, if not create a new client.
  2. If there is a client, then check if we can get number of folders in the Mailbox
  3. If we can get the number, continue using existing client.
  4. If request fails, rebuild client and authenticate from the beginning.

Here is the code adjustment I made:

    if (this.client != null) {
        try {
            // Count number of mail folders in mail box to check health status of existing client.
            Long folderCount = client.me() //
                .mailFolders() //
                .count() //
                .buildRequest() //
                .get();
        } catch (RuntimeException e) {
            logger.debug("Error occured during using existing client, rebuilding the object. Error Message:" + e.getMessage(), e);
            client = createClient();
        }
    } else {
        client = createClient();
    }

And logs when it is executed, first 401 then with new client 200 OK

Error occured during using existing client, rebuilding the object. Error Message:Error code: InvalidAuthenticationToken
Error message: Continuous access evaluation resulted in claims challenge with result: InteractionRequired and code: TokenCreatedWithOutdatedPolicies
GET https://graph.microsoft.com/v1.0/me/mailFolders/$count
SdkVersion : graph-java/v4.0.0
401 : Unauthorized
client-request-id : d2839b0c-ef86-43f0-bcf8-e7c672975ab7
Content-Type : application/json
Date : Wed, 21 Sep 2022 12:58:41 GMT
request-id : 212909ba-09b8-4a92-80a3-9cb8a7eceda3
Strict-Transport-Security : max-age=31536000
Transfer-Encoding : chunked
Vary : Accept-Encoding
WWW-Authenticate : Bearer realm="", authorization_uri="https://login.microsoftonline.com/common/oauth2/authorize", client_id="...", errorDescription="Continuous access evaluation resulted in claims challenge with result: InteractionRequired and code: TokenCreatedWithOutdatedPolicies", error="insufficient_claims", claims="..."
x-ms-ags-diagnostic : {"ServerInfo":{...}}
{
  "error": {
    "code": "InvalidAuthenticationToken",
    "message": "Continuous access evaluation resulted in claims challenge with result: InteractionRequired and code: TokenCreatedWithOutdatedPolicies",
    "innerError": {
      "date": "2022-09-21T12:58:42",
      "request-id": "212909ba-09b8-4a92-80a3-9cb8a7eceda3",
      "client-request-id": "d2839b0c-ef86-43f0-bcf8-e7c672975ab7"
    }
  }
}
    at com.microsoft.graph.http.GraphServiceException.createFromResponse(GraphServiceException.java:419)
    at com.microsoft.graph.http.GraphServiceException.createFromResponse(GraphServiceException.java:378)
    at com.microsoft.graph.http.CoreHttpProvider.handleErrorResponse(CoreHttpProvider.java:509)
    at com.microsoft.graph.http.CoreHttpProvider.processResponse(CoreHttpProvider.java:438)
    at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:404)
    at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:222)
    at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:199)
    at com.microsoft.graph.http.BaseRequest.send(BaseRequest.java:332)
    at com.microsoft.graph.http.PrimitiveRequest.get(PrimitiveRequest.java:66)
Starting to send request, URL https://graph.microsoft.com/v1.0/me/mailFolders?%24top=1000
Request Method GET
Response code 200, OK
cancomert
  • 51
  • 6