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

Web authentication broker authorization APIs or equivalent #171

Closed
Sergio0694 opened this issue May 3, 2020 · 16 comments
Closed

Web authentication broker authorization APIs or equivalent #171

Sergio0694 opened this issue May 3, 2020 · 16 comments
Assignees
Labels
feature request feature request tracked We are tracking this work internally.

Comments

@Sergio0694
Copy link

Sergio0694 commented May 3, 2020

Hello, I'm opening this as a follow up to a conversation with @michael-hawker regarding the introduction of APIs equivalent of the UWP WebAuthenticationBroker.AuthenticateAsync method.

This is commonly used whereas an app needs to let a user login into a cloud service, and makes things pretty easier for the developer as the API takes care of clearing the cookies for the user (so that you don't end up being already logged in by mistake), handling redirect URLs, etc.

Unfortunately that API is a bit unreliable, in that it caused login issues for many developers in the past (including me) when attempting to login into some cloud services (eg. Reddit in my case). To work around that, I built my own authentication broker around the WebView control. Put simply, it first clears the cookies for the current user, then just opens the login URL and waits for a result.

Here's a short version of the code, not as a suggestion but just to illustrate the idea:

<!-- I'm displaying this in a control in a custom popup, but users
     might also show this in a secondary app window or somewhere else. -->
<WebView
    x:Name="AuthWebView"
    NavigationStarting="AuthWebView_NavigationStarting"/>
// Reset the cookies
HttpBaseProtocolFilter myFilter = new HttpBaseProtocolFilter();
HttpCookieManager cookieManager = myFilter.CookieManager;
HttpCookieCollection cookieCollection = cookieManager.GetCookies(navigationUri);
foreach (HttpCookie cookie in cookieCollection)
{
    cookieManager.DeleteCookie(cookie); // Note, will this work with WebView2?
}

 // Navigate to the OAuth 2.0 page
AuthWebView.Navigate(navigationUri);

In my case, that AuthWebView_NavigationStarting handler is simply matching the navigation URL to the expected one and checking whether it contains a code= expression (which includes the login token for Reddit). In all cases, it sets a TaskCompletionSource<string> that I'm awaiting, either with the login token or with null or something else in case of errors.

With WebView2 on the way, it might make sense to offer some easy to use APIs to handle this common scenario (possibly with more customization options, etc.) so that it could easily be used by developers on any framework/language, as long as they're using the WebView2 control. Another option would be to add this as some control/extension to the Windows Community Toolkit, though generally speaking this would restrict the target audience to devs using C#.

The main goal of this issue is simply to investigate how much interest there is around this specific feature, ask for feedback on whether or not it would make sense to make this available as a ready to use and customizable API, and whether this is something that might be made available directly from the WebView2 control, or integrated into some other package/extension (like the toolkit).

Related issue: microsoft/microsoft-ui-xaml#1965
Possibly related: #4

Thanks for your time, keep up the good work! 😊

AB#31944929

@michael-hawker
Copy link

I thought there were also some scenarios that were possible to enable with interop with the browser cookies (I think if the apps for websites had been registered?). This would let the app call this API, but bypass the WebView auth mechanism and receive the token from the user's browser or access cookies for that website from the browser in the app?

Am I mis-remembering this or it related to the Web Account Manager? I can't seem to find the specific piece of documentation that calls this out... 🤷‍♂️

@david-risney david-risney added the feature request feature request label May 4, 2020
@david-risney
Copy link
Contributor

@Sergio0694 Very interesting feature request!

I like the idea of this as a wrapper that can sit on top of a provided CoreWebView2 that can be independent of the UI framework.

Can you elaborate on the issues you face with the existing WebAuthenticationBroker?

@michael-hawker & @Sergio0694 can you comment on requirements around sharing state between callers, or sharing state with the browser for this feature request? WebView2 cannot share state with the browser but can share state otherwise depending on how the user data folder is specified.

@michael-hawker
Copy link

@david-risney in regards to the state sharing, I think the core scenario is that if a user has Edge installed and has already authenticated to a website (Facebook, Instagram, Twitter, etc...). It can be useful for an app that is using those services to be able to make it easier for the user to re-authenticate within the context of the app. Of course, the app would still need to request access to the service like any other with the user's consent, but if that consent has been given and the user has already logged in, it's a pain for the user to have to re-login for the app's use.

@david-risney
Copy link
Contributor

@michael-hawker that makes sense - no special requirements then just it would be better to share state with the browser and if not that at least share state amongst all callers. If I recall correctly, the current WAB doesn't share state with Edge (legacy or new) correct? And it can only share state amongst callers if the caller meets some requirements? Anyway, we'll look into it.

@Sergio0694
Copy link
Author

@david-risney Hey, thank you for your quick reply! 😊

Can you elaborate on the issues you face with the existing WebAuthenticationBroker?

Well, basically I've noticed it's a bit unreliable. For instance, I've been using it for a couple months to login to Reddit in my UWP app. One day Legere changed something in how the remote auth window worked, which apparently broke the login completely for a lot of apps, including mine and other clients on Android too. As a fallback, I switched to that code shown above just using a simple WebView, and it just worked perfectly fine. I just wishes the built-in API would've been more resilient to those type of external changes, seeing how doing it manually with the WebView control worked just fine.

Additionally, sometimes the broker API just kept showing weird errors for some users, which I have not noticed with my solution. I'm not able to provide exact specifications on the issue, I was just left with the impression that doing this manually through a WebView resulted in a more reliable experience overall. Also, being able to integrate the WebView into my own app UI resulted in a nicer experience for users as well from a design perspective.

can you comment on requirements around sharing state between callers, or sharing state with the browser for this feature request?

Personally I'm not particularly interested in being able to grab the logged in status from the brower (although as @michael-hawker mentioned it might be useful for some). I'd just like to have a built-in/easy-to-use way to implement an oauth authentication window in an app using WebView, possibly without having to manually clear cookies every time the window is displayed like I'm doing now. This is needed for apps that support multiple accounts (like Legere does for multiple Reddit accounts) - if I wasn't clearing cookies myself, users trying to add a secondary account would just see the oauth window displaying the "you're already logged in" message for the previously added account.

@weitzhandler
Copy link

weitzhandler commented Aug 21, 2020

The Blazor guys have covered a wide variety of scenarios with their dedicated authentication components, might be worth taking a look at, like this one for instance.

I think it might be valid having a local authentication and token management as part of the .NET or as part of .NET Extensions.

@champnic
Copy link
Member

I think this is a great use case for WebView2, but I don't think we would build this into the control as base functionality. If you end up writing this yourself with WebView2 I encourage you to share it on GitHub, or the community toolkit. Thanks!

@michael-hawker
Copy link

@champnic I believe there'd still be work involved to help facilitate this process on WebView2, I think this issue should still be open. There's a corresponding issue on Reunion here: microsoft/WindowsAppSDK#441

@champnic
Copy link
Member

champnic commented Mar 3, 2021

Hey @michael-hawker - happy to reopen. Do you have a list of the work you think WebView2 needs in order to support this scenario? And if I understand this correctly, the state-sharing with the browser is a nice-to-have (to limit having to re-login) as opposed to a blocker, right?

@champnic champnic reopened this Mar 3, 2021
@champnic champnic added the tracked We are tracking this work internally. label Mar 3, 2021
@champnic
Copy link
Member

champnic commented Mar 3, 2021

I've added this scenario to our backlog. #120 may be related.

@michael-hawker
Copy link

Thanks @champnic, I don't have any concrete list, just trying to help the community, as we know it's a pain-point for many developers trying to integrate with web based REST services like Twitter, Facebook, etc...

State-sharing isn't a complete blocker, but it is usually the first thing we hear our partners and developers ask about when trying to figure out how to get users engaged with their app over their website (or vice versa).

@SymboLinker
Copy link

I don't understand that the discussion in this issue is about working on an OAuth flow via a class named WebView2.

Google does not support WebViews anymore

we will no longer allow OAuth requests to Google in embedded browsers known as “web-views”

and Dropbox is following that path:

Your app should send the user to this app authorization page in their system browser, which [...]

I suspect that those two organisations are not the only two and that it will become a standard for OAuth flows. In other words: a new API should launch the native browser and return to the app with an authentication result.

I found this issue after opening issue xamarin/Essentials#1791 in which I have documented some findings about the AuthenticationBroker. It is unclear to me however which team is responsible for this API - I cannot find the AuthenticationBroker in any public GitHub repository.

@champnic
Copy link
Member

@SymboLinker We're aware of these changes and are working with the AuthenticationBroker team on what our path forwards is. Thanks!

@ArchieCoder
Copy link

This morning, a manager came to me that they could not release their new login workflow because it does not work with IE11. He asked me how to use the Edge engine. Unfortunately, I explained him the bad news that the WebAuthenticationBrowser is antique and it is part of the OS. I could rewrite the SSO experience, but we can't use WebView2 officially yet.

That's being said: it would be truly great to have a new WAB based on Edge sooner than later.

@wbokkers
Copy link

What is the status here?

@champnic
Copy link
Member

Re-closing this item. This is outside the scope of WebView2, though a possible solution may end up using WebView2 and we may need to make targetted fixes if required by the teams that own this. WAB team is aware of this issue, and there's also the open issue on WinAppSDK if they want to build another solution:
microsoft/WindowsAppSDK#441

@michael-hawker If WinAppSDK begins this work and needs specific changes from WebView2 feel free to reach out directly, or open issues/dependencies on what work is needed.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request feature request tracked We are tracking this work internally.
Projects
None yet
Development

No branches or pull requests

9 participants