New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 738724 link

Starred by 10 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 2
Type: Bug



Sign in to add a comment

Chrome tabs not redirecting back to app without user interaction (OAuth2)

Reported by li...@fdna.com, Jul 2 2017

Issue description

Steps to reproduce the problem:
1. Go through OAuth2 process first time and authenticate the user (This works).
2. Try to login again using OAuth2 with chrome tabs
3. With no user interaction Chrome tabs are not closing and the app is not catching the intent.

What is the expected behavior?
Chrome tabs should be closed and the app should catch the intent with the custom scheme even when there is no user interaction.

What went wrong?
Chrome tabs did not close. The app did not catch the intent and the user was unable to login with the OAuth2 provider. 

Did this work before? Yes I don't remeber

Chrome version: 59.0.3071.125  Channel: n/a
OS Version: 7.1.2
Flash Version: 

I'm using AppAuth for the OAuth2 flow. The device I'm using is Google Pixel.
 
Cc: yus...@chromium.org
Components: UI>Browser>Mobile>CustomTabs
I'm experiencing this issue as well. HOwever, I'm not using AppAuth. We're using a hybrid OAauth approach and using our webtier / layer 7 to communicate with Okta. The redirect ONLY works from the password verification flow.

My StackOverflow question describes this in a bit more depth: https://stackoverflow.com/questions/45681456/chrome-custom-tabs-initial-okta-auth-not-redirecting-back
Interestingly enough, I'm only seeing this issue if the user selects the "remember user id" option from the okta log in.

Comment 4 by li...@fdna.com, Aug 17 2017

I think it doesn't matter which library or approach we're using. It seems that without user interaction the user will not be sent back to the app. This means any remember me feature will not work.

Comment 5 by yus...@chromium.org, Aug 21 2017

When you create a custom tab for OAuth, the custom tab sends any intent that is for a custom URI scheme to the client app. I think in your case, the problem is we do not know what the client app is. If you are just using the CustomTabIntent flow and are not connecting to the CustomTabService through CustomTabsClient, there is no way for Chrome to reliably get your app's package name and send the intent back.

See https://github.com/GoogleChrome/custom-tabs-client for examples around service connection.

Here just connecting to the service and calling newSession() on the CustomTabsClient you got, before sending the custom tab would solve this issue.

Please let us know if there are any issues. 
My implementation already uses the recommended CustomTabService implementation and the problem still exists.

Comment 7 by li...@fdna.com, Aug 22 2017

Same here. 
The app does catch the intent the first time. This only happens the second time, where there is no user interaction.

This used to work and our code did not change.

Comment 8 by yus...@chromium.org, Aug 24 2017

Owner: ltian@chromium.org
Status: Assigned (was: Unconfirmed)
I see. Thanks for the clarification. Assigning to Lei to take a look.

Just so that we can do a better job of narrowing down the search, did this start failing on 59 for you?

Lei, looks like somehow we are failing to launch second intent that should have gone to the client app here. And in both cases, that second app is a custom url scheme url that the client app handles. So something changed in the logic where we seem to rely on having received a user gesture for sending the second intent now.

Comment 9 by li...@fdna.com, Aug 28 2017

Not sure when it started. Second consecutive sing-in is a flow we rarely test. I can tell you it worked for me in February and my Google Pixel is always updated.
I'm seeing a similar issue, however we're seeing it every time the user tries to log in. We think we've narrowed down the issue to the fact that _any_ request is made before the user clicks on the "login" button that should (eventually) redirect them to the app. In other words, the flow works when any other request (to any domain) happens within about 5 seconds before the HTTP 302 with a custom scheme URL is delivered to the Android device. If a request is not made, the flow doesn't work and we get an ERR_UNKNOWN_URL_SCHEME page (attached as "android-redirect-fail.png").

Here are some repro steps for the bug using the https://github.com/openid/AppAuth-Android example app:

1. Configure the example app by setting the auth_config.json to be:
> {
>   "client_id": "0oa1zc7uoaD1UdnpB0g7",
>   "redirect_uri": "net.openid.appauthdemo:/oauth2redirect",
>   "authorization_scope": "openid email profile",
>   "discovery_uri": "https://wdawson.trexcloud.com/.well-known/openid-configuration",
>   "authorization_endpoint_uri": "",
>   "token_endpoint_uri": "",
>   "registration_endpoint_uri": "",
>   "https_required": true
> }

2. Install the example app on an Android device (or an emulator)
3. Open the example app and
  a. Click "Start Authorization" (for successful flow)
  b. Type "test" for the username hint and click "Start Authorization" (for failing flow)
4. App should open a Chrome Custom Tab to "wdawson.trexcloud.com"
5. Sign in by
  a. Typing "test" for the username and "Abcd1234"for the password (in the successful non-hinting flow)
  b. Typing "Abcd1234" for the password (in the failing hinting flow)
6. Click "Sign In"
7. Expect that Chrome Custom Tab will redirect the user back to the app after receiving the redirect to the custom scheme
  a. Works as expected
  b. Fails with ERR_UNKNOWN_URL_SCHEME

As I've said before, we've seen the failure occur when there are no other requests made on the page within about 5 seconds of the login occurring. In the successful flow above (without a login hint), the page makes a request to get the user's security image. In the failing flow, no request is made before the login takes place. In our testing, we've noticed that we can make a request via the console to "www.example.com" and the hint flow will work as expected. As such, we don't think it's a problem with our client or server code.

I've also attached the network traces for the two flows that I describe above and we are unable to find any substantial differences, further leading us to believe that this is a chrome issue. Flow (a), the successful one without a login hint, is shown in "success_no_hint.txt", while flow (b), the failing one with the hint, is shown in "no_success_hint.txt".

Please let me know if there are any questions or if I've posted an unrelated bug.

Thanks and looking forward to hearing back

android-redirect-fail.png
218 KB View Download
no_success_hint.txt
29.8 KB View Download
success_no_hint.txt
38.2 KB View Download

Comment 11 by ltian@chromium.org, Jun 11 2018

Cc: ltian@chromium.org
Owner: ----
Status: Available (was: Assigned)
I'm getting similar problem. We have an OAuth2 flow for integration with various third party services (eg. Dropbox, Facebook, Spotify...) orchestrated from our back end. We were trying to shift to Custom Tabs from WebViews (because WebView auth is blocked / discouraged) in the Android client and we look to pass success (with token) / failure response back to the app via custom scheme 302 redirect from our back end. This works in most cases but sometimes we see "Navigation is blocked" as Chrome blocks the final redirect to the app. My understanding was that custom redirect via 302, in the same chain initiated from user entering login details, is a supported flow. This flow works 100% of the time when we try other browsers. If this flow is not supported on Chrome can you explain how we should implement this without needing another user click just to return to the app (Our back up solution is to serve a 200 response with html link that the user has to click to return to the app - this always works).
also note it's not a CustomTabs configuration issue because we have the same pattern of failure (eg. Drobox flow always fails) when launching in separate Chrome browser. Does Chrome block the redirect when there is too big a gap from the original user gesture?
So you're seeing this issue with a server-side redirect (302)? We've had previous reports for client-side (JavaScript) redirects.

But yeah, comment 13 is correct - Chrome tries to route navigations for schemes that it doesn't recognize (eg net.openid.appauthdemo) to an appropriate app through the Android Intents, but doesn't do so when there is not an accompanying user gesture.

Could you try going to chrome://flags on Chrome on your device, searching for #user-activation-v2, enabling this feature, restarting Chrome and trying again?

Comment 15 Deleted

Switching #user-activation-v2 On fixes my issue! Is this coming to production?

(Yes, i'm talking about a server-side redirect)
Cc: mustaq@chromium.org
Adding mustaq@ in case the story has changed.

I believe #user-activation-v2 will launch with M72 which be hitting stable roughly at the end of January.
Labels: UserActivation
Yes, we plan to ship UAv2 in M72.
I am running into the same issue. "Navigation is blocked" on custom URI "myapp://"

This happens for both client side redirects (user-gesture initiated via href on an anchor tag, or javascript function triggered. same behavior either way.)

This also happens on 302 redirect when trying to implement from the server side.

FWIW enabling #user-activation-v2 and restarting shows no change in behavior. This issue is only happening for the Google Chrome web browser app on Android. I am using the Genymotion emulator and have tried on versions 25+ for Android SDK.
#c16 and #c19 shows two different outcomes with respect to chrome://flags/?#user-activation-v2.  May be we are talking about two different problems here, I am not an OAuth expert to be certain.

temitope@gmail.com: Just want to confirm if latest UAv2 code fixes the problem or not. Could you please try your case in Chrome 72+ (dev/canary) with the flag both enabled AND disabled?
@mustaq false alartm! thank you for the response, but it seems that my problem was with the lexicon of the intent filters in the AndroidManifest.xml file. After that I see behavior similar to #c16. I can do a server-side 302 redirect with no problems. But when using the client-side javascript to change "window.location" I still see the "Navigation blocked" warning, thought it allowed me to continue with opening the app on the emulator.

"
But when using the client-side javascript to change "window.location" I still see the "Navigation blocked"
"
This should be expected
I seen lots of comments flows regards this issue. Even I am also facing the same. Do we have any fixes ?

Issue what I am facing :

1. Login into android mobile app with AppAuth framework. (Custom tab able to redirect the uri and close the custom tab properly)
2. Logout the mobile app
3. Login again 
4. Now after successful login, custom tab not closing itself / Navigating back to application .

Debug analysis :
After dig into this issue, I found out that chrome custom tab is "Blocking the navigation" (which prints at console message)

Tried work around:
1. Appended query param "warmup" with true
2. Added "FLAG_ACTIVITY_NO_HISTORY" & "FLAG_ACTIVITY_NEW_TASK" to custom intent
3. Cleared custom tab cookies manually from settings. Nothing worked out. 

Any one have any other solutions for me?
jeyahariprakash@: What's your Chrome/WebView version?
@Mustaq : My chrome version is 71.0.3578.99
This is not specific to UAv2 then.  Seems like a CCT issue.
jeyahariprakash@: But please try the flag in #c14 above anyways and update the bug.

Comment 28 Deleted

I'm facing the same problem. I'm using Okta authentication based on the AppAuth framework.

1. Log in into the app via Custom tabs but the redirection uri is blocked (Navigation is blocked) 
2. Log out from the web browser Chrome on Android. 
3. Log in again, the redirection works and close the custom tab back to the app. 

I also tried many work around like:
1. Added "prompt" with consent (doesn't work)
2. Added the flag chrome://flags/?#user-activation-v2 to enabled (seems to work but I have many devices and I can't set the flag to every devices) 
3. I read about an interstitial page in order to allow the user to consent the redirection via a button to go back to the app. 

Do you have any news about the fix that you're working on ? 
@Mustaq : I tried now with UAV2. It's working fine now. I believe that you are planning to release this update at version 72 at end of this month. 

But do you have any work around for this issue for the current chrome version? Because I cant expect that all my customers should have chrome version 72. It would be better if I can solve this for older version too. 

Regards,
Jeyahariprakash

jeyahariprakash@ : Maybe this will help you, it comes from the AppAuth framework author https://github.com/openid/AppAuth-Android/issues/187#issuecomment-285546334 for a work around
We are also facing this issue, server redirect to app being blocked, and enabling UAV2 does not seem to resolve the issue. Our scenario is:

1. Launch web app in system browser from native app for Open ID Connect login
2. Webapp starts polling on user click (AJAX) and launches another native app (always works)
3. The other native app authenticates the user and returns to the webapp (closes itself)
4. The polling finishes with a 'window.location = X' where X is an path within the web app
5. The web app redirects the user back to the native app, which initiated the login, but the redirect is blocked if the time since the user click was "enough" 

Reading this thread I was expecting that enabling UAV2 should solve the issue but it does not. Any ideas?

My chrome version is 71.0.3578.99


So it sounds like with the old, time based system the time between the click and the window.location update is too long. With UAV2, it sounds like the click was used up opening the other native app, and the webpage has no subsequent click before you attempt to leave Chrome.

I'm assuming (please correct me if I'm wrong) that the native app authenticates the user with some server, which your web app then notices? What is the native app in question - do you have any control over it?
Your assumptions and descriptions are correct. The native app that authenticates the user is the largest eID provider in Sweden (BankID). We can only control the app via a redirect uri which the app launches after completed authentication, or by skipping redirect and letting it close itself. 

Even if we should give the auth app a redirect uri, instead of letting it close itself, I assume that this isn't going to be enough for us to be allowed to redirect/open our initial app? At least this is what my simple tests indicates.

Would using CCT give us more opportunities? 
Update: actually it seems to be allowed both with and without UAV2 to redirect back to the original native app if the auth app redirects back to a new page in the web app (instead of closing itself). 

Important is that the redirect back must not be interpreted as an URL that anchors inside the already open page (same host, path and search with only a different hash) cause then a redirect to a native app is blocked since I guess we have already consumed the user action. For us it would have been nice if a redirect back to an already open page would also be considered a user action. 
Can you give BankID a uri that matches an Intent Filter for your native app? That way BankID would just open your native app and there's no need for it to go back through Chrome?
Not really. The web page is an IDP that needs to be in the loop. However I got everything working now with giving the BankID an new URI back to my web app. This will leave two "trash" tabs from the login flow in the chrome browser but we can live with that and look into CCT to get rid of those. 

What I think you could consider is counting a redirect back (with hash) to an existing open browser tab as a user action. Not sure if this redirect technique it is supported but it works on chrome and safari.

Thanks for your time. 
What specifically do you mean by "redirect back (with hash) to an existing open browser tab"? My understanding is that from Android's point of view the BankID Activity is closed and your page gets a signal and performs a client side (JavaScript) redirect?

Unfortunately it's a security/anti-abuse feature to not let a web page open an application unless there's been a user gesture. Also, when you say it works with "chrome and safari", do you mean on Chrome Desktop?

Custom Tabs do have the same limitation, but if you use a Custom Tab you'll have more of an ability to get rid of tab (and the Activity holding it) once you're finished.
Just to be clear: I have a working work-around now. The following description is just for clarification. 

Originally the BankID app was opened in a click event from the web app and closed it self when done. Since the BankID app took too long time the web app was not allowed to redirect to another native app when it resumed and with UAV2 the click is already consumed. 

Then I tried "redirect back (with hash) to an existing open browser tab" (this is how we do it in Safari since on IOS the app cannot close itself). This is done with the following:

1. Web page assigns a hash to the current location: window.location.href = window.location.href + #random-" + Math.random() (somewhat simplified code)
2. Web page prepares a "redirect back url" with according to the same formula above: redirectUri = window.location.href + #random-" + Math.random() (a new random value is generated so the current URL and the redirect back URL is almost identical)
3. Web page launches the external auth app with the prepared "redirect back url" as a parameter (the launch is fine since it is inside a click event).
4. External auth app does its thing and redirects back to the open page with the "redirect back url" which makes the browser "resume the original open browser tab" (this is what works on both Chrome and Safari on mobile).
5. The web page is now stuck and cannot redirect to an additional app since the "redirect back" isn't counted as a user action (in Chrome).

Our final solution/work-around is to drop the "hash-thing"/"redirect back uri" and just make the BankID app launch a new page since then we are allowed to redirect again out to a native app.

Sorry for any confusion.  

Sign in to add a comment