Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Navigation is blocked" when redirecting from Chrome Custom Tab to Android app

I'm 'modernizing' our login widget to use Chrome Custom Tabs as Google will start blocking OAuth requests using Webviews in a few months.

The login widget works with our Identity Service, which supports classic 'username&password' login and Social Login, by playing the OAuth2 'Client' in an Authorization Code Flow with Google/Facebook/... So the authorization code from Google is delivered to this Identity Service, which in turn provides our login widget with an access token.

The access token is passed back to the mobile app through a client-side redirect:

window.location.replace('com.acmeusercontent.tenants.abc:\/setTokenData?accessToken='+access_token+'#');

All good for a classic login: user fills out username and password and submits, an access token is returned, and the redirect to the custom URI scheme triggers the intent-filter of my RedirectReceiverActivity.

However, for a social login, nothing happens upon the redirect, except for this line in the Android Monitor:

I/chromium: [INFO:CONSOLE(0)] "Navigation is blocked: com.acmeusercontent.tenants.abc:/setTokenData..."

Just to be clear: for both classic and social login, the client-side redirect is exactly the same, but after a classic login it is allowed while after a social login it is blocked!! And, if I add a button to the widget which does the exact same redirect after a social login, it is allowed again - as long as it is clicked by the user.

This leaves me puzzled: - Why is the redirect sometimes allowed and sometimes blocked? - Is there any way to get around this, other than asking the user to click a button after the social login sequence is finished?

I tried everything I could think of: using the "intent:" syntax, simulating a click on the button from code, using a server-side redirect,... but nothing works. Also, I studied the AppAuth libraries with the Google authentication example, and as far as I can tell I'm doing the exact same thing.

like image 221
Free Willaert Avatar asked Jan 07 '17 17:01

Free Willaert


1 Answers

I am the lead maintainer of AppAuth.

The policy on the Chrome side for triggering redirects to an app, whether through a custom scheme or an https App Link, is that this action must be triggered by the user, not Javascript. I believe the intention here is to prevent user surprise where a site opens an application without their explicit "consent" in the form of clicking on a link.

This is problematic for identity providers which immediately redirect back to the redirect URI on an authorization request: no action occurs between opening the custom tab and the redirect.

I maintain a demo that shows how to capture an OAuth redirect and forward it to the app after a user click here:

https://github.com/iainmcgin/AppAuth-Demo

One other potential option is to capture the redirect parameters on your backend, and then respond to the browser with a 302 redirect to your custom scheme. As this maintains a single redirect "chain" from a user action, this should be permitted. Unfortunately this is much more complicated, as you would now likely have to use the OAuth2 state parameter as a key to retrieve the parameters from your server after the app redirect takes place. AppAuth can't directly help with that, as it expects the authorization response to be directly provided to it from the browser.

like image 189
iainmcgin Avatar answered Sep 18 '22 14:09

iainmcgin