Share via

Microsoft.Graph AcquireTokenInteractive is called multiple times on each request to graphClient call.

Jiya desai 56 Reputation points
2023-12-12T16:04:40.9866667+00:00

0

I am seeing a strange behaviour and unable to understand how do i resolve. I see that AcquireTokenInteractive is activated/called on each request of graphClient.Me.

First on await graphClient.Me.GetAsync(); (Which is expected) and secondly on await graphClient.Me.Calendars.GetAsync(); (which is unexpected behavior)

Below is my complete code sample. I am using Microsoft Graph .NET SDK v5


 public class TokenProvider : IAccessTokenProvider  {    

   public AllowedHostsValidator AllowedHostsValidator => throw new NotImplementedException();      
   public IPublicClientApplication publicClientApp;      
 public AuthenticationResult authResult;      


 public async Task<string> GetAuthorizationTokenAsync(Uri uri, Dictionary<string, object> additionalAuthenticationContext = null, CancellationToken cancellationToken = default)
      {
          var scopes = new[] { "Calendars.Read", "User.Read" };
          AuthenticationResult authResult;
          publicClientApp = PublicClientApplicationBuilder.Create("0c-a5-42-a-92")
              .WithRedirectUri("http://localhost")
              .Build();   //Client-id
          try
          {

              var accounts = await publicClientApp.GetAccountsAsync();
              authResult = await publicClientApp.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync();
              return authResult.AccessToken;
          }
          catch (MsalUiRequiredException ex)
          {
              authResult = await publicClientApp.AcquireTokenInteractive(scopes).ExecuteAsync();
              return authResult.AccessToken;
          }

          
      }

     public async Task SignOut()
       {
          var accounts = await publicClientApp.GetAccountsAsync();
          foreach (var account in accounts)
          {
              await publicClientApp.RemoveAsync(account);
           }
         }
      }

In a WPF windows1.cs

TokenProvider tp;
  BaseBearerTokenAuthenticationProvider authenticationProvider;
  GraphServiceClient graphClient;

    public async Task<bool> Button1_Click()
    {
        tp = new TokenProvider();
        authenticationProvider = new BaseBearerTokenAuthenticationProvider(tp);
        Microsoft.Graph.Models.User user = null;

        graphClient = new GraphServiceClient(authenticationProvider);

        user = await graphClient.Me.GetAsync();   // login screen is Called here First Time,  expected.
     }

  public async Task<List<string>> Button2_Click()
  {
      var calendars = await graphClient.Me.Calendars.GetAsync();  // login screen is called here second time, why ?
  }

Hit: Every call to graphClient triggers GetAuthorizationTokenAsync() internally. and during debugging it came to my knowledge that var accounts = await publicClientApp.GetAccountsAsync(); never returns any rows, even if user had login successfully. Where I am wrong in coding?

Microsoft Security | Microsoft Graph
Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

0 comments No comments

Answer accepted by question author

Bruce (SqlWork.com) 84,086 Reputation points
2023-12-12T22:22:12.65+00:00

that is correct, every graphClient instance needs to initial and get the tokens. to limit, your calls should use the same instance rather than create a new one for each call.

Was this answer helpful?


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.