Skip to content
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

WebAuthenticationBroker API that supports all WinAppSDK OS's and application types #441

Open
BenJKuhn opened this issue Feb 11, 2021 · 65 comments
Labels
area-WebView feature proposal maui-7.x Bugs targeted for maui-7.x UWP Gap Issues where functionality available in UWP is missing for Win32 apps

Comments

@BenJKuhn
Copy link
Member

BenJKuhn commented Feb 11, 2021

Proposal: Lifted WebAuthenticationBroker API that supports all Reunion OS's and application types

See #398, #366 - This issue is similar, but distinct in that it covers creating a new, lifted API, rather than updating the existing one to work for more application types.

Summary

Create an API that developers can use in any application type to implement OAuth2 functionality in any app supported by Reunion.

Rationale

The existing OS API that provides this functionality requires a core Window, which, for practical purposes, means that it only works for UWP-style application, and can't be used in other types of applications. Even if the OS API were updated, it would likely only be updated for new OS versions. It would be helpful for developers to have consistent support across OS versions.

https://task.ms/31649739

@mrlacey
Copy link

mrlacey commented Feb 25, 2021

And, of course, this should build on top of WebView2!

Note. The UWP one is based on IE and because of this will not work with many websites, forcing the developer to not be able to use WAB for Oauth with those sites.

@michael-hawker
Copy link

This was originally a request on the WebView2 team here: MicrosoftEdge/WebView2Feedback#171

There's probably some interop involved I believe between Edge, the OS, and WebView2?

@dotMorten
Copy link
Contributor

dotMorten commented Apr 4, 2022

And, of course, this should build on top of WebView2!

I disagree. I'd rather we use the user's default browser to log in, then use protocol activation to come back to the application, as it follows better practices, and is impossible to spoof, and also has the benefit of supporting any saved credentials the user might have in their browser. I managed to actually make this work, but it was a lot of work, lots of code, manifest changes for protocol activation, dealing with app activation args, finding the right instance, shutting down the app if it was the wrong instance, redirecting to the correct instance, then dealing with resuming the authentication workflow there. It was quite non-trivial, and I really wish this could be wayyyyyyyyyyy easier.
I wish there was just a single call I could make that would do all this for me. Something like
public static Task<Uri> OAuthSignIn(Uri authorizationUri, Uri callbackUri); and protocol activation, app instance tracking and resuming etc is just magically handled for me. I shouldn't have to configure my app at all, just configure my oauth with the right callback uri, and then pass it in here.

Another reason to not require webview2: There's no guarantee webview2 is actually available to the user.

@jonwis
Copy link
Member

jonwis commented Apr 4, 2022

app instance tracking and resuming etc is just magically handled for me. I shouldn't have to configure my app at all, just configure my oauth with the right callback uri, and then pass it in here

I agree with everything you've got here - it's important to use the same browser as the user is used to because it may have SSO cookies already set up making the auth basically no-op, or the user might have a password manager associated with it (Edge, LastPass, etc.) where they store their cookies.

For reference, there is https://github.com/Microsoft/cpprestsdk/blob/master/Release/src/http/oauth/oauth2.cpp (and its friend https://github.com/Microsoft/cpprestsdk/blob/master/Release/include/cpprest/oauth2.h), which we'd have to review to see if it behaves correctly. VSCode already does this as well, setting itself up a temporary HTTP server to support the redirect, etc.

@dotMorten
Copy link
Contributor

dotMorten commented Apr 4, 2022

Clever trick with the temporary http server. Very clever actually. There are some challenges though with available ports, and what ports you get to configure in the oauth redirect configuration

@bgavrilMS
Copy link
Member

If you need a reference implementation, please feel free to use MSAL's, it is MIT licensed.

WebView2
WebView1
System Browser using http listner

The discussion around embedded vs system browser is long and inconclusive. When it comes to Azure Active Directory, we've concluded that on desktop it's better to use a broker (WAM on Windows) because brokers increase security and SSO. Internally the broker uses an embedded browser.

Many apps use browsers today and generally the embedded browser are preferred because they provide a better user experience. System browsers are cross-plat but the experience is worse. I have not yet seen any conclusive evidence that system browser is better or worse than embedded browser in terms of security. In terms of SSO, embedded browsers fare poorer, because you are likely to have SSO cookies in your system browser already. But once you start using the embedded browser, it should store the cookies as well.

Hope this helps.

@angelazhangmsft angelazhangmsft changed the title WebAuthenticationBroker API that supports all Reunion OS's and application types WebAuthenticationBroker API that supports all WinAppSDK OS's and application types May 2, 2022
@dotMorten
Copy link
Contributor

Until the WinAppSDK adds this, I've added this ability to WinUIEx v1.4. It's nothing more than a simple one-line call. See https://dotmorten.github.io/WinUIEx/concepts/WebAuthenticator.html

@mattleibow
Copy link

mattleibow commented May 17, 2022

The solution by @dotMorten works well if you are controlling the app, but not so much as a library - and especially as maui which is a framework that libraries will be based on.

The issue is that the auth callback starts a new process - which may be unexpected for the app, and then it also modifies app state unexpectedly (that may override user data or be overridden by user data): https://github.com/dotMorten/WinUIEx/blob/main/src/WinUIEx/WebAuthenticator.cs#L108

The killing of the new process may also be unexpected for the app:
https://github.com/dotMorten/WinUIEx/blob/main/src/WinUIEx/WebAuthenticator.cs#L100

Not sure what the best solution is, but having this in a popup that is controlled by wasdk is more contained and does not require any new processes.

This pop out to a browser works on Android/iOS because even though a "new window" happens, it is the same process and can be intercepted in known places. iOS has a special place, and Android can have a special activity designed for handling callbacks.

Windows on the other hand launches a brand new app.

I appreciate that popping out to the browser is a "better" scenario from the user's credential perspective and default browser, but this is not super windows-friendly. The callback triggers a new proc, which is killed and even if there was a way to share data, Windows doesn't have a place to decide where a new app should be launched or not.

@dotMorten
Copy link
Contributor

it also modifies app state unexpectedly

Note: This only happens if the user didn't already set that state.

Personally I'd like to see something that's a combo of a popup and using the default browser - ie some way a browser knows the request is coming from a specific app and knows to direct you back to that specific app instance and close that tab gain, instead of asking the user to open the app again from the browser - ie overall more akin to what iOS and Android does.

@VR-Architect
Copy link

Any movement or guidance on starting new Maui/WebAPI/BlazorServer combined solution? Is a solution soon?

I am following this Microsoft tutorial but says Windows not working yet.

https://docs.microsoft.com/en-us/dotnet/maui/platform-integration/communication/authentication?tabs=windows

@VR-Architect
Copy link

VR-Architect commented Aug 28, 2022

Will there be a way to leverage the ASP. NET CORE API server as the backend server? All of my various clients, including Blazor Server, already go through the API for DB access. If yes, any chance someone could make a tutorial for this solution setup?

Our goal is 100% of business logic and per-method authorization is contained in the API so our customers could build their own clients if they choose as we are a SaaS provider.

@dotMorten
Copy link
Contributor

@dotMorten
Copy link
Contributor

dotMorten commented Oct 16, 2023

Looks like not only Google, but Facebook has also banned the use of embedded browsers and asking developers to use platform-provided authentication APIs on Android: https://developers.facebook.com/blog/post/2021/06/28/deprecating-support-fb-login-authentication-android-embedded-browsers/
At some point this'll likely come to Windows too.

@Brosten
Copy link

Brosten commented Nov 14, 2023

I'm also having this issue. The workaround suggested might be an option, but please fix! Issues like this makes developers run away from .NET MAUI. :(

@Brosten
Copy link

Brosten commented Nov 14, 2023

I have tried the workarounds from
https://dotmorten.github.io/WinUIEx/concepts/Maui.html#use-winuiexs-webauthenticator-instead-of-net-mauis
and from here
dotnet/maui#2702 (comment)

Both seem to do about the same thing. It does fire up a browser with the login page, however, the created url-parametes gives me 403/forbidden on our auth service.
I can work around this, by using the second workaround and comment out the section manipulating the state parameter in the url. In this case, I'm able to login, but while doing so, my app isn't blocked in the background. I would have hoped this would be the case, or do I need to take care of that myself?
The bigger problem is that when the browser return it doesn't return to my running app, but instead launches a new instance of the app and returns there... Does this has to do with my manipulation of the state parameter? Or am I doing some other mistake?

@dotMorten
Copy link
Contributor

dotMorten commented Nov 14, 2023

@Brosten please, anyone having WinUIEx issues, post them in my WinUIEx repo - let's keep this thread focused on the real issue.

@jbt00000
Copy link

jbt00000 commented Dec 9, 2023

This issue is over 2.5 years old. Is there any reason why the assignee @ujjwalchadha has not commented on this?

@solomonfried
Copy link

Do we know if anyone on the MAUI team is monitoring this issue? This is a critical block for migrating to MAUI.
My Xamarin app that uses WebAuthenticator, already is blocked by Facebook and Apple on UWP from connecting due to its use of IE11.
Hard to understand why this is not begin given the highest priority since most serious apps require Authentication.

Between this issue and the inability to publish MAUI UWP apps that reference a MAUI class library (dotnet/maui#8304), it feels that UWP support for MAUI is being de-prioritized. Wondering if I should drop the platform and only support Android and iOS.

@dotMorten
Copy link
Contributor

Last thing we were told (during community standup I believe), was that it isn't planned for v1.5.

@RobinS-S
Copy link

RobinS-S commented Mar 4, 2024

Can we get some attention on this issue? The problem has existed for quite some time now and prevents simple things such as authentication from working in MAUI for Windows. And I can't imagine MAUI is the only one that uses this.

It's unbelievable how Microsoft is trying to push for a new standard for cross-platform application development but can't manage to make their own OS work with it.

@vukasinpetrovic
Copy link

Is there any other way to implement social logins in MAUI besides using web authenticator? I tried it today and on windows it throws an exception without an actual exception message. I only want to develop desktop app for windows and mac, no mobile needed and I'm scrathing my head over this.

blazor.webview.js:1  
   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|39_0(Int32 hr)
   at ABI.Windows.Security.Authentication.Web.IWebAuthenticationBrokerStaticsMethods.AuthenticateAsync(IObjectReference _obj, WebAuthenticationOptions options, Uri requestUri, Uri callbackUri)
   at Windows.Security.Authentication.Web.WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions options, Uri requestUri, Uri callbackUri)
   at Microsoft.Maui.Authentication.WebAuthenticatorImplementation.AuthenticateAsync(WebAuthenticatorOptions webAuthenticatorOptions)
   at MauiHybrid.Components.Pages.Home.Authenticate()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

@ThreeSevenths
Copy link

Is there any other way to implement social logins in MAUI besides using web authenticator? I tried it today and on windows it throws an exception without an actual exception message. I only want to develop desktop app for windows and mac, no mobile needed and I'm scrathing my head over this.

blazor.webview.js:1  
   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|39_0(Int32 hr)
   at ABI.Windows.Security.Authentication.Web.IWebAuthenticationBrokerStaticsMethods.AuthenticateAsync(IObjectReference _obj, WebAuthenticationOptions options, Uri requestUri, Uri callbackUri)
   at Windows.Security.Authentication.Web.WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions options, Uri requestUri, Uri callbackUri)
   at Microsoft.Maui.Authentication.WebAuthenticatorImplementation.AuthenticateAsync(WebAuthenticatorOptions webAuthenticatorOptions)
   at MauiHybrid.Components.Pages.Home.Authenticate()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

Are you able to implement a protocol handler or run a web server on a port, and do your login via the user's browser? This seems to be the way some apps handle the login problem.

Login in App -> Start web server [optional] -> Open browser to login - > User logs in via browser -> callback url is either https://localhost:10234/login_callback or myawesomeapp://login_callback which gets the token back to you and completes the process.

@solomonfried
Copy link

Thank you @dotMorten
I will try this.

But the question is, if there is a solution why Microsoft can't build it into WebAuthenticator.
You would think that they would want to support their own platform! Authenticating users is essential to most serious applications.

@dotMorten
Copy link
Contributor

dotMorten commented Jul 8, 2024

@solomonfried Preaching to the choir. I've done my fair share of pushing for this, all the way to the point where I had meetings with the team that promised would look into doing this and explaining the reasonings why it is important, but I haven't seen any progress yet. I'm just as puzzled as you, but they are well aware of the limitation at this point, but I don't know what is keeping the priority of this back - I can't really make sense of it.

On the other hand I have no clue why .NET MAUI has left the old UWP implementation in place for MAUI when it doesn't work outside UWP, rather than just deleting all that code and throwing a more helpful PlatformNotSupported exception. Perhaps @PureWeen can answer that.

I created a PR to at least remove the code from MAUI and throw a more helpful error that directs you here.

@codendone codendone added the UWP Gap Issues where functionality available in UWP is missing for Win32 apps label Jul 9, 2024
@vukasinpetrovic
Copy link

@ThreeSevenths Thank you for the info. That seems to be the way of doing it on the desktop apps, which was my main question as to why is web authenticator used (I'm new to desktop development).

@dotMorten And of course, big thank you for your amazin library and fix for web authenticator! I tried it and it works as expected.

@mominshaikhdevs
Copy link

@BenJKuhn @codendone this is a crucial API. whats the latest update on this?

@solomonfried
Copy link

Does anyone know if WebAuthenticator will finally be supported in .NET 9?
Is there an alternative MAUI solution for OAuth? Is there a 3rd party NuGet package? What are all of you doing to manage this?

I am stuck supporting my app on Xamarin because I can't implement a 3rd party login on Windows.

@dotMorten
Copy link
Contributor

dotMorten commented Sep 13, 2024

It's on the 1.7 roadmap.
Did you look at WinUIEx's solution?

@michael-hawker
Copy link

🦙 See 1.7 Plans Discussion which calls this out here: #4710

@solomonfried
Copy link

@michael-hawker, @dotMorten
Thanks for the update.
I guess I'll have to wait till 1.7 is released.
Any estimate on a date?

akanpatel2206 added a commit that referenced this issue Oct 30, 2024
* OAuth2Manager Implementation
API spec: #4772
Issue: #441

This new WinAppSDK version of the AuthManager is different than the existing public
WebAuthenticationBroker
API. We've opted to follow OAuth best practices more closely - e.g. using user's default browser as part of version 1. The best practices for the API are taken from the
IETF(Internet Engineering Task Force) OAuth 2.0 Authorization Framework RFC 6749,
Proof Key for Code Exchange (PKCE) RFC 7636,
and OAuth 2.0 for Native Apps RFC 8252.

It is recommended to read through the mentioned RFCs for better understanding of the design used in the API spec and the implementation code.
Please go through the API spec to understand the implementation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-WebView feature proposal maui-7.x Bugs targeted for maui-7.x UWP Gap Issues where functionality available in UWP is missing for Win32 apps
Projects
None yet
Development

No branches or pull requests