AzureAD / microsoft-authentication-library-for-dotnet

Microsoft Authentication Library (MSAL) for .NET
https://aka.ms/msal-net
MIT License
1.39k stars 342 forks source link

[Bug] Microsoft.Windows.Client does not work with WinUI (.Net 6.0) #4790

Closed COMADD closed 4 months ago

COMADD commented 4 months ago

Library version used

4.61.1

.NET version

WinUI (.Net 6.0)

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

Hello,

I migrated my UWP project to WinUI-3 and calling "Microsoft.Windows.Client" version 4.61.1 returns the same error: Only loopback redirect uri is supported, but urn:ietf:wg:oauth:2.0:oob was found. Configure http://localhost or http://localhost:port both during app registration and when you create the PublicClientApplication object. See https://aka.ms/msal-net-os-browser for details

I tried with version 4.59 and the result is the same. So as it stands, Microsoft.Windows.Client is unusable for a WinUI-3 project!

Best regards.

Relevant code snippets

PublicClientApplicationBuilder PCAB = PublicClientApplicationBuilder.Create(_clientId);
_IdentityClientApp = PCAB.Build();
IEnumerable<IAccount> accounts = await _IdentityClientApp.GetAccountsAsync();
AuthenticationResult authResult;
try
{
   authResult = await _IdentityClientApp.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync();
}
catch (MsalUiRequiredException ex)
{
  Debug.WriteLine(ex.Message);
  authResult = await _IdentityClientApp.AcquireTokenInteractive(scopes).ExecuteAsync();
}

Expected behavior

I would like to acquire a token correctly.

Identity provider

Azure B2C Basic Policy

Regression

No response

Solution and workarounds

I don't have any other solution or workaround!

bgavrilMS commented 4 months ago

I will help with this @COMADD

bgavrilMS commented 4 months ago

Note that we do have a sample for Maui app (which includes WinUI) + B2C: https://github.com/Azure-Samples/ms-identity-dotnetcore-maui/tree/main/MauiAppB2C

But to streamline the process, here's what you need to do:

  1. Add a reference to Microsoft.Identity.Client.Desktop and to Microsoft.Identity.Client.Extensions.Msal (same version as MSAL)
  2. When you construct your PublicClientApplication add WithWindowsEmbeddedBrowserSupport()

Try it now. If there are still issues with the redirect URI, please set it explicitly via WithRedirectUri

The 3rd step you need to do add token caching. See https://learn.microsoft.com/en-us/entra/msal/dotnet/how-to/token-cache-serialization?tabs=desktop

COMADD commented 4 months ago

I added a reference to Microsoft.Identity.Client.Desktop and to Microsoft.Identity.Client.Extensions.Msal

I modified my code to have :


PublicClientApplicationBuilder PCAB = PublicClientApplicationBuilder.Create(_clientId);
_IdentityClientApp = PCAB
                    .WithWindowsEmbeddedBrowserSupport()
                    .Build();

I get the error No account or login hint was passed to the AcquireTokenSilent call.

With my current UWP application MSAL automatically opens a window like this: https://devblogs.microsoft.com/surface-duo/wp-content/uploads/sites/53/2023/03/login-tablet-768x570.png

I would like to have the same behavior with the migration of the project to WinUI-3. That is to say that I would like the user of my application to be able to enter their own login credentials.

bgavrilMS commented 4 months ago

Right, AcquireTokenSilent will throw that exception. Then the execution flow goes to AcquireTokenInteractive doesn't that pop up a browser window?

COMADD commented 4 months ago

Please forgive me, I didn't remember how this code works. AcquireTokenSilent() returns an error the first time (which is normal). Then in the catch() of this error AcquireTokenInteractive() opens an identification window (like for UWP) and the identification works correctly.

So I believe that the migration of this code is operational for WinUI-3 and I thank you.

bgavrilMS commented 4 months ago

Sure, glad it works @COMADD .

malsabi commented 3 months ago

Hello @bgavrilMS I'm using .NET MAUI and the latest version of MSAL Library 4.61.3 however I'm getting the same exception too.

Packages Installed:

  1. Microsoft.Identity.Client 4.61.3
  2. Microsoft.Identity.Client.Extensions.Msal 4.61.3

Note: This used to work completely fine on 4.59.1

Here is my code that is used to handle authentication in different platforms, however the issue happened in Windows, I didn't test for Android / iOS. Can you please tell me what is required here to make it work ?


    public AuthenticationService(IOptions<AuthenticationSettings> authenticationSettings)
    {
        this.authenticationSettings = authenticationSettings.Value;

        authenticationClient = PublicClientApplicationBuilder.Create(this.authenticationSettings.ClientId)
#if IOS
            .WithIosKeychainSecurityGroup("com.microsoft.adalcache")
#endif
            .WithRedirectUri($"msal{this.authenticationSettings.ClientId}://auth")
#if ANDROID
            .WithParentActivityOrWindow(() => Platform.CurrentActivity)
#endif
            .Build();
    }

    public async Task<AuthenticationResult?> LoginAsync(CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();
        try
        {
#if WINDOWS
            await AttachTokenCache();
#endif
            return await authenticationClient
                .AcquireTokenInteractive(authenticationSettings.Scopes)
#if WINDOWS
                .WithUseEmbeddedWebView(authenticationClient.IsEmbeddedWebViewAvailable())
#endif
                .ExecuteAsync(cancellationToken);
        }
        catch (MsalClientException)
        {
            return null;
        }
    }
bgavrilMS commented 3 months ago

Hi @malsabi - can you please open a new bug and reference the old one.