Calls to Microsoft Graph API when using government endpoint does not work, but works for global endpoint?

Jake Bluhm 1 Reputation point
2021-04-12T13:44:16.907+00:00

The software I am creating needs to get Microsoft Teams presence (Available, Busy, Away, etc.) from MS Graph. The company I work for uses the global service, and the software works as expected for my co-workers.

I am testing the deployment of the software and I am running into a problem where calls to MS Graph for US Government to get Microsoft Teams presence fails with the following exceptions:

86928-error3.png

This link (https://learn.microsoft.com/en-us/graph/deployments) explains the difference between MS Graph endpoints, and includes a video that outlines how to make MS Graph calls to users in that end point. The video seems to say that all you need to do to change endpoints is change the MS Graph Api URL and the Login URL.

I will post snippets of code (cannot post full code) that leads to the errors is below. First on application launch, in app.xaml.cs I configure MSAL following this doc (https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-net-initializing-client-applications)

private static string InstanceGov = "https://login.microsoftonline.us/";  
private static string Tenant = "common";  
  public partial class App : Application  
    {  
        static App()  
        {  
            _clientApp = PublicClientApplicationBuilder.Create(ClientId)  
                .WithAuthority($"{InstanceGov}{Tenant}")  
                .WithDefaultRedirectUri()  
                .Build();  
            TokenCacheHelper.EnableSerialization(_clientApp.UserTokenCache);  
        }  
    .  
    .  
    .  
    }  

Then the user signs into MS 365, no problems here:

     public async void Sign_In()  
        {  
            AuthenticationResult authResult = null;  
            var app = App.PublicClientApp;  
            ////ResultText.Text = string.Empty;  
   
  
  
              
  
            var accounts = await app.GetAccountsAsync();  
            var firstAccount = accounts.FirstOrDefault();  
  
            try  
            {  
                authResult = await app.AcquireTokenSilent(scopes, firstAccount)  
                    .ExecuteAsync();  
  
          
  
  
                this.ConnectButton.Visibility = Visibility.Collapsed;  
                this.SignOutButton.Visibility = Visibility.Visible;  
                ErrorInfo.Visibility = Visibility.Hidden;  
                Timer1.Start();  
  
            }  
            catch (MsalUiRequiredException ex)  
            {  
                // A MsalUiRequiredException happened on AcquireTokenSilent.   
                // This indicates you need to call AcquireTokenInteractive to acquire a token  
                System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");  
  
                try  
                {  
                    authResult = await app.AcquireTokenInteractive(scopes)  
                        .WithAccount(accounts.FirstOrDefault())  
                        .WithParentActivityOrWindow(new WindowInteropHelper(this).Handle) // optional, used to center the browser on the window  
                        .WithPrompt(Prompt.SelectAccount)  
                        .ExecuteAsync();  
  
  
                    this.ConnectButton.Visibility = Visibility.Collapsed;  
                    this.SignOutButton.Visibility = Visibility.Visible;  
                    ErrorInfo.Visibility = Visibility.Hidden;  
  
  
                    Timer1.Start();  
                }  
                catch (MsalException msalex)  
                {  
                    ////ResultText.Text = $"Error Acquiring Token:{System.Environment.NewLine}{msalex}";  
                    System.Windows.MessageBox.Show($"Error Acquiring Token:{System.Environment.NewLine}{msalex} "  , "Error",  
                        (MessageBoxButton)MessageBoxButtons.OK, (MessageBoxImage)MessageBoxIcon.Error);  
  
                    this.ConnectButton.Visibility = Visibility.Visible;  
                    this.SignOutButton.Visibility = Visibility.Collapsed;  
                    status_light.Fill = Brushes.Black;  
                    ErrorInfo.Visibility = Visibility.Visible;  
                    ErrorText.Text = "Please Sign in";  
                }  
            }  
            catch (Exception ex)  
            {  
                ////ResultText.Text = $"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}";  
  
                this.ConnectButton.Visibility = Visibility.Visible;  
                status_light.Fill = Brushes.Black;  
                ErrorInfo.Visibility = Visibility.Visible;  
                ErrorText.Text = "Please Sign in";  
                return;  
            }  
            if (authResult != null)  
            {  
                signinstring = "Sign Out";  
            }  
            //else  
            //{  
            //    Environment.Exit(0);  
            //}  
  
              
        }  

Next, I make a call to get the Microsoft Teams presence data. This results in an exception in the image above.

 public partial class MainWindow : Window  
    {  
        //Set the API Endpoint to Graph 'me' endpoint.   
        // To change from Microsoft public cloud to a national cloud, use another value of graphAPIEndpoint.  
        // Reference with Graph endpoints here: https://learn.microsoft.com/graph/deployments#microsoft-graph-and-graph-explorer-service-root-endpoints  
        string graphAPIEndpoint = "https://graph.microsoft.com/v1.0/me";  
        string graphPresenceEndpoint = "https://graph.microsoft.com/v1.0/me/presence";   
        string graphPresenceEndpointGov = "https://graph.microsoft.us/v1.0/me/presence";  
  
   ...  
   ...  
   ...  
  
   void some_function()  
   {  
      status_string = await GetHttpContentWithToken(graphPresenceEndpointGov , authResult.AccessToken);   
     ... // ^ Throws exception ^  
     ...  
     ...  
   }  
}  

The software works only when using the global endpoint, we have confirmed by sending software sample to others outside the company also using global endpoint. When using MS Graph for users not using the global endpoint is there anything I am missing that could be causing this?

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,716 questions
Microsoft Teams Development
Microsoft Teams Development
Microsoft Teams: A Microsoft customizable chat-based workspace.Development: The process of researching, productizing, and refining new or existing technologies.
2,886 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,665 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Jake Bluhm 1 Reputation point
    2021-04-16T14:45:19.393+00:00

    @Mamatha-MSFT thank you,

    The use of https://login.microsoftonline.us/ is taken from this documentation . My understanding is that this step is needed to get a token.

    Towards the bottom of my post I do use https://graph.microsoft.us in this line of code:
    string graphPresenceEndpointGov = "https://graph.microsoft.us/v1.0/me/presence";

    Testing your suggestion with the global endpoint, I changed the following code and got the exception below:

    private static string Instance = "https://graph.microsoft.com";//"https://login.microsoftonline.com/";  
    
    
     _clientApp = PublicClientApplicationBuilder.Create(ClientId)  
                     .WithAuthority($"{Instance}{Tenant}")  
                     .WithDefaultRedirectUri()  
                     .Build();  
                 TokenCacheHelper.EnableSerialization(_clientApp.UserTokenCache);  
    

    88569-exception.png