MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
440 stars 51 forks source link

[UPDATE] Google Auth Flows and WebView2 #1647

Closed jasonstephen15 closed 11 months ago

jasonstephen15 commented 3 years ago

Google has recently made a policy update to prohibit Google OAuth requests in embedded browsers (webviews). This means that google auth flows will not be supported in WebView2.

Our short-term recommendation for a workaround is to launch the system browser and handle the auth flow there. Google’s OAuth Sample repo has an example of how to do this. This solution will work for all app types.

Longer term, our suggestion will be to use the Web Authentication Broker (WAB) API. The WAB API is a Windows API, vetted by Google, that will enable auth flows in your native applications. This API is currently UWP-only but has plans to be available in win32 and .NET as part of the WindowsAppSDK. Please follow the team’s GitHub post for updates on that. For more guidance on how to build out these auth flows visit the WAB Sample Code.

Feel free to leave any comments or questions below. Thanks!

markismail7 commented 3 years ago

This is not a solution. I'm not blaming Microsoft for it. Google is a dictator. We need to move away from Google products. The only way we can do so, if Microsoft creates a Gmail. Until then, we are all screwed. The is could get way worse, the sign in with Google is a disaster right now. We can't use it with WebView2. When WebView2 was announced, I was so excited. A powerful, fast, updated Browser embedded to .NET Application. This has been a dream for All Microsoft Developers. And now all of sudden after less than year of it's launch. Google decided to prevent us from accessing Gmail from inside Webview2. Wow.

GrandStrateguerre commented 3 years ago

@markismail7 For me it's already done I don't use Google anymore. I use: https://www.qwant.com/ The only application I use that has an interest for me is Youtube mainly for knowledge sharing. I have forbidden my children to use Google and FaceBook apps. :) G.

rjx-ray commented 3 years ago

We are CEF users thinking about moving to WebView2, just waiting for https://github.com/MicrosoftEdge/WebView2Feedback/issues/20 to be progressed.

We have faced exactly this authentication issue in CEF and after some considerable effort I managed to get an OAuth access token by spawning an external browser. from our app. See my post at https://www.magpcss.org/ceforum/viewtopic.php?f=10&t=17457#p45389 with example code attached.

But as it explains in the post I have been unable to find any way of using the token for general web requests.

If anyone here has any ideas that would be very useful

markismail7 commented 3 years ago

So if I use the OAuth, the user can sign in with the main browser, then once the user is signed in, the user can go back to use Webview2? It's like scratching your ear with your toe SMH. It's like we have nothing to do, but to work extra for google. Imagine every website is doing the same thing. I'm really surprised that most people are ok with it?

jarno9981 commented 3 years ago

Rrrrrrrrr is swichtes from cef sharp to webview2 to use google login and now it breaks again i pissed off now

jarno9981 commented 3 years ago

@markismail7 i hate the security change from google now my app loses lot of funtions 40hours of work gone now

federicorosso1993 commented 3 years ago

Can you help me with the workaround? I understand that I need to use Google’s OAuth API on the native browser, and I used that some months ago in a Unity3d game to access google drive and upload/download a save file, but I don't really understand how to do that to be able to be logged in in a browser-like app (my current webview2 don't really just need to access a google service like gmail or drive like in my unity game, I'm using my webview2 as a real browser so I cannot just ask to access gmail o google drive, I need to be able to navigate to any google related service and use it, like youtube). The example use a Loopback to get the log in response but in the end it just print the response as a string, that's not a solution at all. What we really need (to call this a workaround) is to be able to set that response to the webview2 "cookies/cache/localstorage/whatever google is using to know that the browser is logged in". That's a "good" workaround. The best workaround would be something even better... a blackbox solution where the webview2 open an edge window->make the user log in inside edge->set whatever google need to know that webview2 is logged into the webview2.

Not sure why you think WAB is a solution here... That's only a solution in the same way Oauth is a solution, when you know how to set the response into webview2 to make it know you are logged in. Finally I have to say that I find many answer here unrealistic... I don't think any user will leave google just because of this. Still I think their security solutions are just really stupid... there is no reason why I should not be able to log in to my own application in a webview2, if the browser is not supported google should just tell you to log in with an alternative method (like the apps password or something like that). I don't really understand why I cannot even trust my own webview2 browser-like app. Also when I made that game unity3d and used the google drive api, I was also able to do the same thing with dropbox and microsoft one drive. Dropbox was the best (the docs API is amazing), Microsoft was ok (I needed to contact you on github because the docs were not clear), Google API was the worst and behind everyone (you cannot even make a call without the client-secret even if you use PKCE while everybody else if you use PKCE do not require client-secret and that's a security problem on their Oauth call for desktop app).

PS. I think the solution on this post https://github.com/MicrosoftEdge/WebView2Feedback/issues/1669#issuecomment-902966984 is the way to go. It will not require to write new code from the developers part (just update the webview2 to the last version) and it will actually work as a solution to the man in the middle for the log in part without removing the ability to use the webview2 as a real browser in a native apps (with all the good thing that can be made with that combination). You should really go with the "system webview" by default on the login page of google.

markismail7 commented 3 years ago

@federicorosso1993 I did update to the latest version, still having the same issue. How did you fix it?

federicorosso1993 commented 3 years ago

@federicorosso1993 I did update to the latest version, still having the same issue. How did you fix it?

I did not fix it. By solution I mean what should be done by Microsoft, but the problem is still there

markismail7 commented 3 years ago

Why are we paying the price for Google's problem. When a user attempts to sign in with Google, let the Webview2 opens the Chrome Edge, then after signing in, it'll load automatically back to Webview2. That's a solution. Not make me register my app for something I'm not familiar with. This whole thing is stupid. Real Hackers don't need a browser to attack Google. SMH. I don't think it's about security.

haiduong87 commented 2 years ago

Here's a practice from gg. https://github.com/googlesamples/oauth-apps-for-windows

I can't point the different between my own way and this suggestion. I'm doing as:

federicorosso1993 commented 2 years ago

Here's a practice from gg. https://github.com/googlesamples/oauth-apps-for-windows

I can't point the different between my own way and this suggestion. I'm doing as:

  • Show a webiview2 web login page
  • Handle navigating events to grab the key
  • Call rest api to get token

Can you use this sample to navigate on a webview2 after the login like in a regular browser for all the Google website like Gmail and YouTube?

I would like the user to be able to use my app as a browser and only use the real browser during log in, is that possible?

I used a little of Google drive API for another project and I know how to ask the user the Auth code from an app and wait for the log in response, but after that I can only make another api call to access Google drive files with my own interface, I cannot set that token in a webview2 to make the user able to navigate in Google drive logged in.

That's the main problem to solve

haiduong87 commented 2 years ago

Here's a practice from gg. https://github.com/googlesamples/oauth-apps-for-windows I can't point the different between my own way and this suggestion. I'm doing as:

  • Show a webiview2 web login page
  • Handle navigating events to grab the key
  • Call rest api to get token

Can you use this sample to navigate on a webview2 after the login like in a regular browser for all the Google website like Gmail and YouTube?

I would like the user to be able to use my app as a browser and only use the real browser during log in, is that possible?

I used a little of Google drive API for another project and I know how to ask the user the Auth code from an app and wait for the log in response, but after that I can only make another api call to access Google drive files with my own interface, I cannot set that token in a webview2 to make the user able to navigate in Google drive logged in.

That's the main problem to solve

That's not my use case, so I haven't tested that.

But I think it's ok,

About the HttpListener, I have never used that before, may be there's firewall problem.

federicorosso1993 commented 2 years ago

That's not my use case, so I haven't tested that.

But I think it's ok,

About the HttpListener, I have never used that before, may be there's firewall problem.

Don't really know what are you talking about for the httplistener, I don't have a problem with that in my other project. The problem is only with my last project where I use a webview2 as a browser and there is no way to log in to Google and watch YouTube videos after that in my own browser like app. If I can only make a oauth2 call to get the video Flux and watch it in my own interface that will only work for YouTube but not for Google drive or Gmail then there is no reason to use a webview in the first place. Of course I cannot only use my interface because I also need my browser to work on all website (not just Google services). It's crazy how difficult they made it just because they refuse to make an alternative for the Google log in... It's not even possible to use a password application like you can do for older outlook.

Beej126 commented 2 years ago

Here's a practice from gg. https://github.com/googlesamples/oauth-apps-for-windows I can't point the different between my own way and this suggestion. I'm doing as:

  • Show a webiview2 web login page
  • Handle navigating events to grab the key
  • Call rest api to get token

Can you use this sample to navigate on a webview2 after the login like in a regular browser for all the Google website like Gmail and YouTube?

@federicorosso1993, yes this sample works fine with webview2 and doesn't require any additional google login for gmail, youtube, etc... it's easy to confirm yourself as i have... add webview2 control (with Name="wv2") to bottom of existing window, then replace the one line that spawns external browser:

System.Diagnostics.Process.Start(authorizationRequest);

with webview2 equivalent:

wv2.Source = new Uri(authorizationRequest);

it appears the webview2 browser instance maintains full fidelity... we can hit F12 to open typical chrome debugger tools window and inspect that google's login cookies are indeed present.

@jasonstephen15 , @markismail7, @jarno9981, @64Soft, @Simon4638 - i'm mainly posting because i want to better understand what roadblocks you are running into, so i don't waste time going down a dead end for my own project...

it seems embedded browser approach is still functionally viable... so is this entirely about the change in google's policy? i.e. we're running afoul of rules if we continue to use embedded, even if it works?

maybe latest webview2 (v1.0.992.28 stable, published 2021-09-27) closed previous gaps?

federicorosso1993 commented 2 years ago

@Beej126 thank you for trying it. I'll try to undestand how to implement it in my own app.

jarno9981 commented 2 years ago

@Beej126 thank i am going to try to

jarno9981 commented 2 years ago

@Beej126 still doesn't log me in only on edge browser

. { "sub": "100246938796268582855", "name": "Jarno", "given_name": "Jarno", "picture": "https://lh3.googleusercontent.com/a-/AOh14Ghy0fzITDxtGU_GT6Qw75eTyPTDuK3yaqDXqtReiA\u003ds96-c", "locale": "nl" }

and returns this in the textbox of the browser

but when i try to login it says unsafe app Winforms

jarno9981 commented 2 years ago

@Beej126

after email in external browser shows correct api info but still not abble to login Schermafbeelding 2021-10-05 070948

after trying to login in email Schermafbeelding 2021-10-05 071019

Beej126 commented 2 years ago

if i understand you, you're hoping that embedded webview2 login is shared with external browser... that might be possible with further effort but that's not going to work by default ... i believe they are running under separate "user profiles", i.e. a different bucket of all the browser state, cookies, etc

i misunderstood your desired scenario... what i am looking for, and what i thought you all were looking for, was that after you use webview for google oauth flow, you can also then count on the google auth login to be present under the webview for other google sites, youtube, gmail, etc

jarno9981 commented 2 years ago

@Beej126 I want to by abble to login from winforms app that correct

jarno9981 commented 2 years ago

when redirect url is active this shows Schermafbeelding 2021-10-05 072109

this is what textbox says : https://www.google.com/redirect URI: http://127.0.0.1:61965/ Listening..

jarno9981 commented 2 years ago

this after email clicked Schermafbeelding 2021-10-05 072233

Beej126 commented 2 years ago

i guess you're not doing what i said, to modify the sample to use the webview2? i'll post a fork of the project with what i mean here in a few mins.

Beej126 commented 2 years ago

this fork has the embedded webview tweak i'm suggesting in the wpf sample: https://github.com/Beej126/oauth-apps-for-windows

first image shows the oauth flow in the embedded webview second image shows i can also jump right into youtube after the oauth flow (without logging in again) image image

jarno9981 commented 2 years ago

@Beej126 i will try that like that your doing

jarno9981 commented 2 years ago

returns this for me

Schermafbeelding 2021-10-05 092052

no refresh

Beej126 commented 2 years ago

try running my sample as-is and let us know what happens.

jarno9981 commented 2 years ago

Schermafbeelding 2021-10-05 093848

sample app returns same for me

@Beej126

Beej126 commented 2 years ago

ok now that's interesting! i am trying to think of variables in play here and i remember seeing something about the running webview2 binary is running on top of the version of msedge you have installed... i'm running msedge 64bit v94.0.992.38... also make sure to at least try loading the msedge DEV build, i remember seeing something about that dependency.

since you're running my project, you should have 1.0.1018-prerelease of webview2 assembly but double check that. here's the release notes page that ties versions of webview2 to msedge. https://docs.microsoft.com/en-us/microsoft-edge/webview2/release-notes

For full API compatibility, this prerelease version of the WebView2 SDK requires Microsoft Edge version 95.0.1018.0 or higher...

which is interesting, i just updated msedge and didn't get v95, so that could be a DEV build#, which means you should try installing latest DEV build msedge

the only other thing i can think of right now is i am running Win11 (version 21H2, build 22000.194)... but i don't think that's a dependency here

thanks for sharing that screenshot, it really proves (for everybody) there is something odd going on here.

you should also try fiddling with:

wv2.CoreWebView2.Settings.UserAgent = "copy this from working browser";

https://stackoverflow.com/questions/67549605/set-useragent-in-webview2/67550089#67550089

watch for differences like that comparing the debug windows of a working browser and not working webview2 (remember f12 opens debug)... i feel like webview2 might be sending a useragent that's tripping off google, but just a wild hunch ... since i can't repro on my end i can't help you here.

better yet, just trying temporarily spoofing the useragent string in debug tools and hit refresh: https://developer.chrome.com/docs/devtools/device-mode/override-user-agent/

here's a page that shows what user agent is being sent, plug this into webview2 to see what it's sending by default: https://www.whatismybrowser.com/detect/what-is-my-user-agent

let me know how that goes

here's mine:

image

jarno9981 commented 2 years ago

@Beej126 my useragent is

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36 Edg/94.0.992.31

webview2 useragent

Beej126 commented 2 years ago

ok well scratch that idea, that looks totally normal... i would definitely upgrade all the msedge stack including installing msedge dev build to cross that angle off your list.

total longshot but if you're not on win11 and desperate i would try spinning up a win11 vm and running my project to see if any difference.

jarno9981 commented 2 years ago

@Beej126 I am on win11 bete channel

I am going to try edge dev next

jarno9981 commented 2 years ago

@Beej126 even with edge dev same result unable to login not safe error

Winforms

Beej126 commented 2 years ago

image

general

Request URL: https://accounts.google.com/o/oauth2/v2/auth?response_type=code&scope=openid%20profile&redirect_uri=http%3A%2F%2F127.0.0.1%3A9810%2F&client_id=581786658708-elflankerquo1a6vsckabbhn25hclla0.apps.googleusercontent.com&state=83_ClWKyPX8s__FAFSjIC5noEie8YbZC7c--4umkZLc&code_challenge=Cn470IYGFw-bO11du2LJtPYoCYonZVLLNMWofsjhiT4&code_challenge_method=S256 Request Method: GET Status Code: 200 Remote Address: 172.217.14.205:443 Referrer Policy: strict-origin-when-cross-origin

response headers

alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43" cache-control: no-cache, no-store, max-age=0, must-revalidate content-encoding: gzip content-security-policy: script-src 'report-sample' 'nonce-AG3on8/fwioIY4p51neqyg' 'unsafe-inline' 'unsafe-eval';object-src 'none';base-uri 'self';report-uri /cspreport content-type: text/html; charset=utf-8 date: Tue, 05 Oct 2021 19:00:08 GMT expires: Mon, 01 Jan 1990 00:00:00 GMT pragma: no-cache server: GSE set-cookie: [redacted] strict-transport-security: max-age=31536000; includeSubDomains x-content-type-options: nosniff x-frame-options: DENY x-xss-protection: 1; mode=block

request headers

:authority: accounts.google.com :method: GET :path: /o/oauth2/v2/auth?response_type=code&scope=openid%20profile&redirect_uri=http%3A%2F%2F127.0.0.1%3A9810%2F&client_id=581786658708-elflankerquo1a6vsckabbhn25hclla0.apps.googleusercontent.com&state=83_ClWKyPX8s__FAFSjIC5noEie8YbZC7c--4umkZLc&code_challenge=Cn470IYGFw-bO11du2LJtPYoCYonZVLLNMWofsjhiT4&code_challenge_method=S256 :scheme: https accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9 accept-encoding: gzip, deflate, br accept-language: en-US,en;q=0.9 cookie: [redacted] sec-ch-ua: "Chromium";v="94", "Microsoft Edge";v="94", ";Not A Brand";v="99" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" sec-fetch-dest: document sec-fetch-mode: navigate sec-fetch-site: none sec-fetch-user: ?1 upgrade-insecure-requests: 1 user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Edg/94.0.992.38

query string parms

response_type: code scope: openid profile redirect_uri: http://127.0.0.1:9810/ client_id: 581786658708-elflankerquo1a6vsckabbhn25hclla0.apps.googleusercontent.com state: [redacted] code_challenge: [redacted] code_challenge_method: S256

jarno9981 commented 2 years ago

@Beej126

for me it returns this Schermafbeelding 2021-10-06 110119

jarno9981 commented 2 years ago

this in headers Schermafbeelding 2021-10-06 111154

Beej126 commented 2 years ago

it would be the request headers going off to google that they could pick up on and decide block you (i only see response headers in that screenshot)

but help me know something for my own needs - can you load youtube into my sample app and see if you are allowed to login via the normal flow present on the youtube page? or do you get the block there as well?

(use the app menu icon in the upper right corner of google.com to select youtube.) image

jarno9981 commented 2 years ago

@Beej126 still same for me

federicorosso1993 commented 2 years ago

@Beej126 I tried your code with my own client id, secret id (btw you should not share those, but you need to tell what scopes did you use). It's not working and I don't really see how can it work for you. On the first solution (System.Diagnostics.Process.Start(authorizationRequest);) you will only get a text response (that works of course) on an external browser. So the OAuth2 part it's working like it should. But once you go back to the app the webview2 it's not logged (of course). On the second solution it redirect you correctly to the API app but you will not be able to log in like in the regular log in page.... There is no difference between trying to log in on the regular google page https://accounts.google.com/signin/v2/identifier?flowName=GlifWebSignIn&flowEntry=ServiceLogin and the one that you use when you do that with the oauth2 code https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?response_type=code&etc.... They both say your browser is not supported for security reason after you input your email and you try to press the Continue button so you can get here: https://user-images.githubusercontent.com/6301228/135968815-c85a3ddc-e2bd-4e3b-8477-cda7cc058302.png

But you will not get after that.

Not sure why you can... maybe you only got a cache on your webview2 or maybe the windows 11 preview was still not blocked when you posted the message that's the only way I can explain this.

What we need to understand is once you make the API call to an external browser (like you did with the first solution) and you get a response (and we need to understand what scopes are needed there for all google services) how to set that info into the cookies / localstorage or something like that to be able to sign in on the webview2. That's the main point to solve, your first solution is not complete and the second solution does not work.

PS. The user agent is not the problem. It's the same as yours and it's the first thing I tried when I got the main problem. The MiM attack is not a good thing, but the fact that I cannot even trust my own app it's a problem. There is no alternative way to log in, not even app password work. And there is no supported solution right now to solve this, not from google, not from microsoft.

Beej126 commented 2 years ago

@federicorosso1993, appreciate your detailed response...

real quick, those aren't my client id & secret... those are straight out of google's sample code, so no risk there but i appreciate the consideration =)

lemme digest what you've said and i'll respond further... it is a mystery that mine works... and i just started doing this a few days ago so feels doubtful i have cached bits but who knows given the timing of everything that's in flux here.

can you check your end for that "X-Requested-With" request header mentioned in the article a few posts up.

federicorosso1993 commented 2 years ago

@Beej126 Already checked, it's the same.

Beej126 commented 2 years ago

@federicorosso1993, please clarify? same as what? i don't have one present, if you do, that could be significant.

federicorosso1993 commented 2 years ago

I mean the same as yours, no X-Requested-With present. I just checked every field I didn't remember X-Requested-With specifically.

Beej126 commented 2 years ago

quick video to show actually working on my end https://youtu.be/KamrZHCWnK0 for the record, it is spliced to eliminate my verbal ticks and hide sensitive info but it's a true take i'm wide open to check on anything

markismail7 commented 2 years ago

PayPal has already solved this problem by opening an external window during entering a credit card information. Why Google won't do the same?

Beej126 commented 2 years ago

@markismail7 - thanks for chiming in... i saw you on the other thread and roped you in here because i'm wanting to hear from as many different experiences as possible, but the external browser token auth flow DOES work fine and isn't the problem here...

what i'm looking for (and i believe others on this thread), is having an embedded browser in the native app that lets you get into google pages that require auth, gmail, youtube, etc... i am hearing this is currently being blocked by google for everybody??... except me somehow, for the moment... i'm keen to understand why so that i can count on this and not build stuff that then breaks when mine stops working as well.

federicorosso1993 commented 2 years ago

@Beej126 that's really strange... I would said that it has something to do with windows 11 and edge, but since I'm still on windows 10 but jarno9981 should have tried it on windows 11 already. Also like I said I think there is a possibility your version is just so updated that google has not blocked it yet... I think they would update this if it was a fix from microsoft. I can get to 0:49 on your video, I cannot reach the 0:54 (so no, it was one step after what you said on the video). Out of curiosity, can you log in without calling the API? Or do you get blocked if you try to log in the regular way? Because if it does work without the API it should be easy to understand it's the edge version thing, but if it does block you the API should have something to do with it.

PS. I think you mistanderstand what markismail7 was suggesting... The idea was to just input the login info in a pop up protected window of the webview2 to log in and after that go back to the regular webview2 logged in. It could even work with an external browser if we could just translate the way google see that you are logged in into another browser (cookies, localstorage etc...).

@markismail7 yeah that would be the best solution... for all of us. Easy and transparent. I mean if the external window is in a more protect environment problem solved, and everybody is happy. At the end we don't want to use log in info at all, we just need to be able to log in to google services in a webview2.

Beej126 commented 2 years ago

@federicorosso1993 - thanks for settings me straight on what you and @markismail7 have been saying, namely, a protected popup coming out of the webview flow, now i get it... @markismail7 - apologies for being patronizing =)

weird you can't play past 0:49 on video, i just checked it again... maybe retry in a fresh session of something... this extension still seemed to work just now for downloading youtube videos as a last resort

yes, i can totally login without the api flow... i can go straight to youtube in the webview2 (triple checked by clearing all my session cookies via debug window) and google will prompt for login and lets me right in

i guess i'm going to keep implementing this direction with fingers crossed... worst case i will pull true msedge.exe windows into my app panels via win32 setparent window handle api calls... done it before, with windows explorer, and that code still works on win11 just fine and i really doubt they could ever disable that brute force approach.

jarno9981 commented 2 years ago

@Beej126 which webview2 runtime pakage do you have maybe thats de problem for me