-
Notifications
You must be signed in to change notification settings - Fork 49
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
[Auth] Use custom IBrowser for OIDC/MSAL #2640
Comments
Poking @carldebilly / @nickrandolph for anymore info that we need for this one. Doing this will allow us to no longer rely on the |
Why would you want to remove the dependency on Web Auth Broker? It's a robust mechanism and less proprietary than the IBrowser interface. In the latest WinUI, Microsoft introduced a new Actually, I did something slightly different: instead of customizing the IBrowser interface specific to EntityModel.OidcClient (now renamed The missing piece is the custom Web Authentication Broker (WAB), which uses my "new" http server. This server is extremely lightweight, has no dependencies, and is far easier to use than Kestrel. Check it out here: https://www.nuget.org/packages/Yllibed.HttpServer/1.0.0-dev.10.ge2ac37743f#readme-body-tab Code: #if HAS_UNO_SKIA
using System.Diagnostics;
using System.Runtime.InteropServices;
using Windows.Security.Authentication.Web;
using Uno.AuthenticationBroker;
using Uno.Foundation.Extensibility;
using Yllibed.HttpServer;
using Yllibed.HttpServer.Handlers;
[assembly:
ApiExtension(typeof(IWebAuthenticationBrokerProvider), typeof(SystemBrowserAuthBroker))]
namespace MyApp.Services.Auth;
public sealed class SystemBrowserAuthBroker : IWebAuthenticationBrokerProvider
{
private Server? _server;
private Uri? _serverRootUri;
public Uri GetCurrentApplicationCallbackUri()
{
return new Uri(EnsureServerStarted().RootUri, "/auth-callback");
}
public async Task<WebAuthenticationResult> AuthenticateAsync(WebAuthenticationOptions options, Uri requestUri,
Uri callbackUri, CancellationToken ct)
{
if (options.HasFlag(WebAuthenticationOptions.SilentMode))
{
throw new NotSupportedException("SilentMode is not supported by this broker.");
}
if (options.HasFlag(WebAuthenticationOptions.UseTitle))
{
throw new NotSupportedException("UseTitle is not supported by this broker.");
}
if (options.HasFlag(WebAuthenticationOptions.UseHttpPost))
{
throw new NotSupportedException("UseHttpPost is not supported by this broker.");
}
if (options.HasFlag(WebAuthenticationOptions.UseCorporateNetwork))
{
throw new NotSupportedException("UseCorporateNetwork is not supported by this broker.");
}
var (server, _) = EnsureServerStarted();
var authCallbackHandler = new AuthCallbackHandler(callbackUri);
using (server.RegisterHandler(authCallbackHandler))
{
OpenBrowser(requestUri);
return await authCallbackHandler.WaitForCallbackAsync();
}
}
private (Server Server, Uri RootUri) EnsureServerStarted()
{
if (_server is null || _serverRootUri is null)
{
_server = new Server();
(_serverRootUri, _) = _server.Start();
}
return (_server, _serverRootUri);
}
public static void OpenBrowser(Uri uri)
{
var url = uri.AbsoluteUri;
try
{
Process.Start(url);
}
catch
{
// hack because of this: https://github.com/dotnet/corefx/issues/10361
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
url = url.Replace("&", "^&");
Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true });
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Process.Start("xdg-open", url);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ||
RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD))
{
Process.Start("open", url);
}
else
{
throw;
}
}
}
private sealed class AuthCallbackHandler(Uri callbackUri) : IHttpHandler
{
private readonly TaskCompletionSource<WebAuthenticationResult> _tcs = new();
public Task HandleRequest(CancellationToken ct, IHttpServerRequest request, string relativePath)
{
if (request.Url.AbsolutePath.StartsWith(callbackUri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
{
var result = new WebAuthenticationResult(
request.Url.OriginalString,
200,
WebAuthenticationStatus.Success);
_tcs.TrySetResult(result);
request.SetResponse("text/plain", "Auth completed - you can close this browser now.");
}
return Task.CompletedTask;
}
public Task<WebAuthenticationResult> WaitForCallbackAsync()
{
return _tcs.Task;
}
}
}
#endif |
Use something similar to https://github.com/IdentityModel/IdentityModel.OidcClient.Samples/blob/main/NetCoreConsoleClient/src/NetCoreConsoleClient/SystemBrowser.cs for a browser implementation that can support net-desktop targets
I believe @carldebilly has a modified version of this that can do away with the Kestrel dependency.
The text was updated successfully, but these errors were encountered: