-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug] Maui Essentials WebAuthenticator not working in WinUI #2702
[Bug] Maui Essentials WebAuthenticator not working in WinUI #2702
Comments
Did you add the extension into your Package.appxmanifest? <Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="MyApp.App">
<Extensions>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="myapp">
<uap:DisplayName>My App</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
</Application>
</Applications> |
Yeah, here's the Package.appxmanifest file from this sample app. <?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="DC54F990-A6CD-4BED-B2AE-1942F4470BCC"
Publisher="CN=User Name"
Version="1.0.0.0" />
<Properties>
<DisplayName>MauiAppSample</DisplayName>
<PublisherDisplayName>Microsoft</PublisherDisplayName>
<Logo>Assets\appiconStoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="MauiAppSample"
Description="MauiAppSample"
BackgroundColor="transparent"
Square150x150Logo="Assets\appiconMediumTile.png"
Square44x44Logo="Assets\appiconLogo.png">
<uap:DefaultTile
Wide310x150Logo="Assets\appiconWideTile.png"
Square71x71Logo="Assets\appiconSmallTile.png"
Square310x310Logo="Assets\appiconLargeTile.png"
ShortName="MauiAppFileInput">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo"/>
<uap:ShowOn Tile="wide310x150Logo"/>
</uap:ShowNameOnTiles>
</uap:DefaultTile >
<uap:SplashScreen Image="Assets\appiconfgSplashScreen.png" />
</uap:VisualElements>
<Extensions>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="io.identitymodel.native">
<uap:DisplayName>MauiAppSample</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package> |
In MainPage.xaml.cs I have a using directive for OidcClient (and a few others that can be easily resolved in the editor) using IdentityModel.OidcClient Variables OidcClient _oidcClient;
LoginResult _loginResult; and a method to handle a login button click: async void OnLoginButtonClicked(object sender, EventArgs e)
{
var options = new OidcClientOptions
{
Authority = "https://demo.identityserver.io",
ClientId = "interactive.public",
Scope = "openid profile email api offline_access",
RedirectUri = "io.identitymodel.native://callback",
Browser = new Browser()
};
_oidcClient = new OidcClient(options);
_loginResult = await _oidcClient.LoginAsync(new LoginRequest());
if (_loginResult.IsError)
{
Console.WriteLine("ERROR: {0}", _loginResult.Error);
return;
}
} And the Browser.cs file. As I mentioned initially, I'm calling WebAuthenticator.PlatformAuthenticateAsync(authenticatorOptions) in my local file. Except for a few namespace adjustments to prevent conflicts and the adjustment to line 51, it's the same file as what's used in Maui Essentials. using IdentityModel.OidcClient.Browser;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace MauiAppSample
{
public class Browser : IBrowser
{
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
{
var authenticatorOptions = new Microsoft.Maui.Essentials.WebAuthenticatorOptions
{
CallbackUrl = new Uri("io.identitymodel.native://callback"),
Url = new Uri("https://demo.identityserver.io")
};
// WebAuthenticator.PlatformAuthenticateAsync is in a local file that's altered to locate the
// AppxManifest.xml file, as mentioned in my initial post.
Microsoft.Maui.Essentials.WebAuthenticatorResult authResult =
await WebAuthenticator.PlatformAuthenticateAsync(authenticatorOptions);
return new BrowserResult()
{
Response = ParseAuthenticatorResult(authResult)
};
}
string ParseAuthenticatorResult(Microsoft.Maui.Essentials.WebAuthenticatorResult result)
{
string code = result?.Properties["code"];
string scope = result?.Properties["scope"];
string state = result?.Properties["state"];
string sessionState = result?.Properties["session_state"];
return $"{"io.identitymodel.native://callback"}#code={code}&scope={scope}&state={state}&session_state={sessionState}";
}
}
} |
Any news about this? Same error here |
Sorry, no news. I'm still experiencing it too. |
Same error |
Same here |
any news i have same error too? |
same error |
I've tried on a couple of different computers but the reason is the same. Also, I've tried clean installation of Maui & workloads, and tried on cleanly installed windows but nothing changed. It tries to find Then, I've tried to check my I think there might be an error in
Could anyone get over this issue? |
Reproduce on windows with VS2022 17.2.0 Preview 2.0 [32215.517.main], attach repro sample |
I believe there was a bug in the packaging process before. @Eilon I think there was an issue at some point where the targets were copying the Package.appxmanifest into the root of the package and this caused some issues. I can't seem to locate the issue I am thinking of, but I felt it was maybe the blazor content copying being too happy and grabbing all files or something? |
Any updates on the issue? I have been facing the exactly same issue in windows with the latest Release Candidate. |
Here's one implementation that can probably be more or less lifted as is into MAUI: https://github.com/dotMorten/WinUIEx/blob/main/src/WinUIEx/WebAuthenticator.cs |
Thanks for the repo, @dotMorten . I tried using this class as replacement. It is now able to open the browser, initiate the authentication and redirect back to the application, but immediately after that, throws a "invalid state" error within the oidc client. On closer inspection, the value for the "state" key in the returned WebAuthenticatorResult.Properties (from AuthenticateAsync) seems quite different from what is received on a similar android project. |
@shv07 Mind opening an issue over in the WinUIEx repo and we can discuss there, but I'm guessing you're adding a |
On a slightly different note but still related to the WebAuthenticator. On Android the documentation for Xamarin Essentials, it still only supports Android 11 or SDK 30. Will this be updated? Because if you target Android 12 as of right now and use the WebAuthenticator you will get an error which says "java crashed with exit code 1" |
@jayveedee I was able to fix that error by setting My final Activity was like this:- // MainActivity.cs
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
DataScheme = "myapp")]
public class WebAuthenticationCallbackActivity : WebAuthenticatorCallbackActivity
{
} |
@shv07 can you send a PR to the docs? |
@jamesmontemagno Sure, done. MicrosoftDocs/xamarin-docs#3455 |
@davidbritch did you mean to close this with a doc pr? |
@dotMorten No, apologies! |
Status update: The following issue can be tracked: |
Any news about this ? |
I was able to get my MAUI WinUI app to log in successfully, primarily with the help of the code provided up above by @dotMorten.
Just copy that code into a file called something like I did have one issue with an exception throwing in my OIDC Client Browser that said "Invalid state". It turned out being that the state information being added in the new Web Authenticator class (appInstanceId & signinId) wasn't expected while building the using IdentityModel.OidcClient.Browser;
using System.Diagnostics;
namespace MyAwesomeMauiApp.WinUI;
public class Browser : IdentityModel.OidcClient.Browser.IBrowser
{
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
{
try
{
Microsoft.Maui.Authentication.WebAuthenticatorResult authResult =
await WinUIEx.WebAuthenticator.AuthenticateAsync(new Uri(options.StartUrl), new Uri("myapp://callback")); // Add your callback URL
var authorizeResponse = ToRawIdentityUrl(options.EndUrl, authResult);
return new BrowserResult
{
Response = authorizeResponse
};
}
catch (TaskCanceledException ex)
{
Debug.WriteLine(ex);
return new BrowserResult
{
ResultType = BrowserResultType.UserCancel
};
}
catch (Exception ex)
{
Debug.WriteLine(ex);
return new BrowserResult()
{
ResultType = BrowserResultType.UnknownError,
Error = ex.ToString()
};
}
}
public string ToRawIdentityUrl(string redirectUrl, WebAuthenticatorResult result)
{
try
{
IEnumerable<string> parameters = result.Properties.Select(pair => $"{pair.Key}={pair.Value}");
var modifiedParameters = parameters.ToList();
var stateParameter = modifiedParameters
.FirstOrDefault(p => p.StartsWith("state", StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(stateParameter))
{
// Remove the state key added by WebAuthenticator that includes appInstanceId
modifiedParameters = modifiedParameters.Where(p => !p.StartsWith("state", StringComparison.OrdinalIgnoreCase)).ToList();
stateParameter = System.Web.HttpUtility.UrlDecode(stateParameter).Split('&').Last();
modifiedParameters.Add(stateParameter);
}
var values = string.Join("&", modifiedParameters);
return $"{redirectUrl}#{values}";
}
catch (Exception ex)
{
Debug.WriteLine(ex);
throw;
}
}
} |
Closing this as it is a bug in the Windows App SDK and is being tracked there: microsoft/WindowsAppSDK#441 |
I'm attempting to use WebAuthenticator in Maui Essentials to authenticate a WinUI project, but it's having an issue finding the manifest file. It throws an exception saying:
Could not find file 'C:\WINDOWS\system32\AppxManifest.xml'.
If I add a local version of https://github.com/dotnet/maui/blob/main/src/Essentials/src/WebAuthenticator/WebAuthenticator.uwp.cs into my project (I made PlatformAuthenticateAsync public to test it and just passed the url and callbackUrl in the WebAuthenticatorOptions) and adjust line 51 to:
It then finds the file, however, a new error is thrown that says:
System.Runtime.InteropServices.COMException: 'There are no remote procedure calls active on this thread. (0x800706BD)'
Additionally, I set the CallbackUrl to:
and the Url to:
The text was updated successfully, but these errors were encountered: