dotMorten / WinUIEx

WinUI Extensions
https://dotmorten.github.io/WinUIEx
MIT License
602 stars 38 forks source link

Invalid State errror on using with OidcClient #40

Closed shv07 closed 2 years ago

shv07 commented 2 years ago

I tried using the WebAuthenticator class with OidcClient library as a replacement for Microsoft.Maui.Authentication.WebAuthenticator in a Maui desktop application. Unlike the latter, the web browser opens now and on receiving the credentials, redirects back to the application. But the when the returned WebAuthenticatorResult object causes Invalid State error in OidcClient library.

If I instead, use the WinUIEx.WebAuthenticatorResult class too, I get Malformed Callback Url error.

The code works perfectly when used on Android with Maui's WebAuthenticator. On closer inspection, the value for the "state" key in the returned WebAuthenticatorResult.Properties dictionary (from AuthenticateAsync() method) seems quite different from what is received on a similar android project.

The relevant piece of code which calls the method of this class is here:-

internal class WebAuthenticatorBrowser : IdentityModel.OidcClient.Browser.IBrowser
    {
        private readonly string _callbackUrl;

        public WebAuthenticatorBrowser(string callbackUrl = null)
        {
            _callbackUrl = callbackUrl ?? null;
        }
        public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
        {
            try
            {
                var callbackUrl = string.IsNullOrEmpty(_callbackUrl) ? options.EndUrl : _callbackUrl;

#if WINDOWS
               // THIS IS WHERE THE DIFFERENCE IS WITH ANDROID. Here, authResult.Properties dictionary contains
               // a key "state" whose value seems very different from that in case of android
                var authResult =
                    await WinUIEx.WebAuthenticator.AuthenticateAsync(new Uri(options.StartUrl), new Uri(callbackUrl));
#else
                // Executed in android
                WebAuthenticatorResult authResult =
                    await WebAuthenticator.AuthenticateAsync(new Uri(options.StartUrl), new Uri(callbackUrl));
#endif
                var authorizeResponse = ToRawIdentityUrl(options.EndUrl, authResult);

                return new BrowserResult
                {
                    Response = authorizeResponse
                };
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                return new BrowserResult()
                {
                    ResultType = BrowserResultType.UnknownError,
                    Error = ex.ToString()
                };
            }
        }

        public string ToRawIdentityUrl(string redirectUrl, WebAuthenticatorResult result)
        {
            IEnumerable<string> parameters = result.Properties.Select(pair => $"{pair.Key}={pair.Value}");
            var values = string.Join("&", parameters);

            return $"{redirectUrl}#{values}";
        }

#if WINDOWS
        public string ToRawIdentityUrl(string redirectUrl, WinUIEx.WebAuthenticatorResult result)
        {
            IEnumerable<string> parameters = result.Properties.Select(pair => $"{pair.Key}={pair.Value}");
            var values = string.Join("&", parameters);

            return $"{redirectUrl}#{values}";
        }
#endif
    }
dotMorten commented 2 years ago

Do you have a state parameter in the authentication url? Could you share the url you use? (Feel free to obfuscate some of the parameters but keep the gist of it)

dotMorten commented 2 years ago

Also when you say the state parameter is different what is it in WinUIEx and what is it in Maui?

shv07 commented 2 years ago

When using with Maui (in Android), the state parameter is something like oQo5B7yiFBin9DmyNSacjT, whereas while using with WinUIEx (in Windows), it is like:- appInstanceId=f232469d-80cf-4e79-8994-8f568eb7bcf6&signinId=06cded67-erf5-5e25-9925-490841bb29ca.

The auth url I use points to https://localhost:5000 (where my identity server is running)

dotMorten commented 2 years ago

Thanks for confirming. I submitted a fix

shv07 commented 2 years ago

Thanks for the prompt response!

dotMorten commented 2 years ago

v1.4.2 should be available on nuget in 10-15 mins. Let me know if that fixes it for you

shv07 commented 2 years ago

v1.4.2 works perfectly as expected. Appreciate the help.

dotMorten commented 2 years ago

Awesome. Thanks for pointing this one out.