microsoft-ui-xaml icon indicating copy to clipboard operation
microsoft-ui-xaml copied to clipboard

"Parameter is incorrect" when using WebAuthenticationCoreManagerInterop

Open yoshiask opened this issue 3 years ago • 3 comments

Describe the bug

Calling WebAuthenticationCoreManagerInterop.RequestTokenForWindowAsync(hwnd, request) from a WinUI 3 Desktop app always returns with a status of ProviderError. The error message is as follows:

The parameter is incorrect.

onecoreuap\shell\cloudexperiencehost\onecore\app\msa\core\TokenRequestParams.cpp(175)\MicrosoftAccount.TokenProvider.Core.dll!00007FFA3DA5453D: (caller: 00007FFA3DA88115) Exception(1) tid(73b8) 80070057 The parameter is incorrect.
    CallContext:[\RequestTokenAsyncActivity] 

The error persists regardless of whether my package is associated with the Microsoft Store.

Steps to reproduce the bug

  1. Create a new WinUI 3 Desktop project (either single-project or WAP, neither work)
  2. Add the following to MainWindow.xaml.cs, along with the necessary using statements:
private AccountsSettingsPane _asp;
private AccountsSettingsPane _hwnd;

public MainWindow()
{
    this.InitializeComponent();
    _hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
}

private async void OnLoaded(object sender, RoutedEventArgs e)
{
    _asp = AccountsSettingsPaneInterop.GetForWindow(_hwnd);

    _asp.AccountCommandsRequested += Asp_AccountCommandsRequested;
    await AccountsSettingsPaneInterop.ShowAddAccountForWindowAsync(_hwnd);
}

private async void Asp_AccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs args)
{
    var deferral = args.GetDeferral();

    var msaProvider = await WebAuthenticationCoreManager.FindAccountProviderAsync(
        "https://login.microsoft.com", "consumers");

    var command = new WebAccountProviderCommand(msaProvider, GetMsaTokenAsync);
    args.WebAccountProviderCommands.Add(command);

    deferral.Complete();
}

private async void GetMsaTokenAsync(WebAccountProviderCommand command)
{
    WebTokenRequest request = new(command.WebAccountProvider, "wl.basic");

    WebTokenRequestResult result = await WebAuthenticationCoreManagerInterop.RequestTokenForWindowAsync(_hwnd, request);

    if (result.ResponseStatus == WebTokenRequestStatus.Success)
    {
        string token = result.ResponseData[0].Token;
    }
}

Expected behavior

Successfully retrieve account information using the Web Account Manager.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.1.3

Windows app type

  • [ ] UWP
  • [X] Win32

Device form factor

Desktop

Windows version

Windows Insider Build (xxxxx)

Additional context

It appears that a similar issue #5827 was reported last year, but closed because it use WinUI 3 UWP.

yoshiask avatar Jul 28 '22 03:07 yoshiask

The trace output line (thank you!) points to a check that the app provides BOTH an application callback URI and a client ID. The code above doesn't set ClientId - https://docs.microsoft.com/en-us/uwp/api/windows.security.authentication.web.core.webtokenrequest.clientid?view=winrt-22621#windows-security-authentication-web-core-webtokenrequest-clientid so maybe start there? There's a three-parameter form of the WebTokenRequest constructor that takes the provider, scope, and client ID together. See also this sample:

https://github.com/microsoft/Windows-universal-samples/blob/ad9a0c4def222aaf044e51f8ee0939911cb58471/Samples/WebAccountManagement/cs/SingleMicrosoftAccountScenario.xaml.cs#L179-L189

jonwis avatar Aug 18 '22 06:08 jonwis

I have seen a similar issue when accessing onedrive files from a WinUI desktop app compared to a UWP app even when using a manifest file with the same package id. I could get it working by copying some code from the msal library:

webTokenRequest.Properties.Add("api-version", "2.0"); // request V2 tokens over V1
webTokenRequest.Properties.Add("oauth2_batch", "1"); // request tokens as OAuth style name/value pairs
webTokenRequest.Properties.Add("x-client-info", "1"); // request client_info

However, I am not sure why this is necessary.

lhak avatar Aug 25 '22 09:08 lhak

The trace output line (thank you!) points to a check that the app provides BOTH an application callback URI and a client ID. The code above doesn't set ClientId - https://docs.microsoft.com/en-us/uwp/api/windows.security.authentication.web.core.webtokenrequest.clientid?view=winrt-22621#windows-security-authentication-web-core-webtokenrequest-clientid so maybe start there? There's a three-parameter form of the WebTokenRequest constructor that takes the provider, scope, and client ID together. See also this sample:

https://github.com/microsoft/Windows-universal-samples/blob/ad9a0c4def222aaf044e51f8ee0939911cb58471/Samples/WebAccountManagement/cs/SingleMicrosoftAccountScenario.xaml.cs#L179-L189

The sample you linked has a comment that says "ClientID is ignored by MSA". Even when I do set a client ID, I get this error:

The application requesting authentication tokens is either disabled or incorrectly configured.

onecoreuap\shell\cloudexperiencehost\onecore\app\msa\core\TokenProviderExecutor.cpp(1037)\MicrosoftAccount.TokenProvider.Core.dll!00007FFFE91E0FA0: (caller: 00007FFFE91BED19) Exception(4) tid(5d58) 80860003 The application requesting authentication tokens is either disabled or incorrectly configured.

yoshiask avatar Sep 06 '22 02:09 yoshiask

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 5 days.

github-actions[bot] avatar Jul 28 '23 22:07 github-actions[bot]