Skip to content

When running code to acquire access token AcquireTokenInteractive never returns never  #4598

Open
@dgxhubbard

Description

Library version used

4.59.0

.NET version

.net 7

Scenario

PublicClient - desktop app

Is this a new or an existing app?

The app is in production, and I have upgraded to a new version of MSAL

Issue description and reproduction steps

I run the code in my wpf application and the call to AcquireTokenInteractive never returns and does not show any UI to choose a user. I place the same code in a command line app and get UI to select user and send test email.

Relevant code snippets

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.Identity.Client;


namespace TestAccessToken
{
    internal class Program
    {
        public static string ClientId = "c266bdd1-d87e-44d5-a5db-f153234068a2";
                                         
        public static string Tenant = "common";
        public static string Instance = "https://login.microsoftonline.com/";

        public static string RedirectUri = "http://localhost";
        public static string Authority = "https://login.microsoftonline.com/common/";

        static async Task Main ( string [] args )
        {
            var stoppingToken = new CancellationToken ();
            string accessToken = null;

            AuthenticationResult authenticationResult = null;


            Console.WriteLine ( "Press any key to start the authentication process." );
            await Task.Run ( Console.ReadKey ).WaitAsync ( stoppingToken );


            var scopes =
                new List<string> ()
                {
                            "email",
                            "offline_access",
                            //"https://outlook.office.com/IMAP.AccessAsUser.All", // Only needed for IMAP
                            //"https://outlook.office.com/POP.AccessAsUser.All",  // Only needed for POP
                            "https://outlook.office.com/SMTP.Send", // Only needed for SMTP
                };


            var clientApp = 
                PublicClientApplicationBuilder.
                    Create ( ClientId ).
                    WithAuthority ( Authority ).
                    WithRedirectUri ( RedirectUri ).
                    Build ();

            if ( clientApp == null )
                throw new NullReferenceException ( "FAILED to create client app builder" );

            var accounts = await clientApp.GetAccountsAsync ();

            IAccount firstAccount = null;
            
            if ( accounts != null )
                firstAccount = accounts.FirstOrDefault ();

            var success = false;
            try
            {
                authenticationResult = await clientApp.AcquireTokenSilent ( scopes, firstAccount ).ExecuteAsync ();

                if ( authenticationResult != null )
                    accessToken = authenticationResult.AccessToken;

                success = true;
            }
            catch ( Exception ex )
            {
                Console.WriteLine ( "Could not acquire token silent " + ex.Message );
            }


            if ( !success )
            {
                try
                {
                    authenticationResult = await clientApp.AcquireTokenInteractive ( scopes )
                        .ExecuteAsync ();

                    if ( authenticationResult != null )
                        accessToken = authenticationResult.AccessToken;
                }
                catch ( MsalException msalex )
                {
                    Console.WriteLine ( "Error Acquiring Token" + msalex.Message );
                }
            }



        }
    }
}

Expected behavior

I expect the code to allow user to login and send test email. Right now the command line app works but it does not appear that a token is stored because AcquireTokenSilent always throws an exception. The code to get first account also always returns null:

        var accounts = await clientApp.GetAccountsAsync ();

        IAccount firstAccount = null;
        
        if ( accounts != null )
            firstAccount = accounts.FirstOrDefault ();

Identity provider

Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)

Regression

4.54.0

Solution and workarounds

None

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions