403: disallowed_useragent for web login from embedded browsers

There was a past thread about this, but it was closed without being answered: Google - Disallowed user agent when using Auth0 Lock

I also cross-posted this question to Stack Overflow, and from there linked a couple other relevant Stack Overflow questions.

Google disallowed logging into Google from webviews a few years ago, and Auth0 also made a blog post about workarounds, but it all seems to focus on native apps, not web apps that offer Google as a login option.

But my company’s app is a web-app, and we’d like it if when someone shares a link to our site on Facebook Messenger/Facebook posts, users can log in with Google even if they don’t pop out the native Safari browser. Based on the above documentation it would seem that that’s not possible - but actually I discovered that Pinterest’s “Sign in with Google” button does work! So it appears there’s a way to get Google login working (not sure if they swung a special deal with Google, or if they’re doing something we/Auth0 can be doing too, though).

Repro steps:

  1. Open Facebook Messenger in iOS (this should roughly work with Facebook too, but this demonstrates the issue)
  2. Send yourself a message with the URL https://community.auth0.com
  3. Click on the link to the Auth0 Community forum
  4. Click on Log In
  5. Click on Log in with Google
  6. See that you get a 403: disallowed_useragent error.

And to prove that there does seem a way for this to be done in the wild:

  1. Ensure Pinterest isn’t installed on your iOS device so links to it don’t open in-app
  2. Open Facebook Messenger in iOS
  3. Send yourself a message with the URL https://pinterest.com
  4. Click on the Pinterest link
  5. Click on “Sign in with google”
  6. Somehow, it doesn’t error when Pinterest does it!

What does the Auth0 team/community think? Thanks!

3 Likes

EDIT: some more details from looking at the Google OAuth endpoint URLs my site vs Pinterest’s:

Looking at the Google oauth URL my site uses vs Pinterest’s, I see a few differences:

  1. Mine goes to https://accounts.google.com/o/oauth2/auth, theirs goes to https://accounts.google.com/o/oauth2/auth/identifier
  2. Theirs has a few extra query parameters mine doesn’t:
["openid.realm", ""]
["ss_domain", "https://www.pinterest.com"]
["fetch_basic_profile", "true"]
["gsiwebsdk", "2"]
["flowName", "GeneralOAuthFlow"]
  1. Theirs has a different value for response_type of permission id_token, mine is code

not sure what has an effect though.

1 Like

Hi does anyone have an update? I have the same problem!

1 Like

Any update on this? I’m having the same issues.

No response from anyone at Auth0 regarding this??

1 Like

Any update on this ? I’m having the same issue here, wihtin LinkedIn.

Any update. Facing similar problems with an Ionic application when navigating from Instagram link. Internal web_client causing Google to refuse to authenticate.

@osdiab did you find any solution?
Pinterest has removed Google login when navigation is from mobile. That means that even this big enterprise did not find any solution for those embedded login.
Is it possible in Auth0 to hide Google login in specific case? For instance I would check for the user agent and then decide if I display or not the social login.

For anyone who encounter this issue, I found a hack: use CSS property to hide google signin button in case user is on a mobile navigation. Go to Auth0 dashboard, then Branding > Login. Open Login tab and use navigator.userAgent to detect mobile navigation and override CSS dynamically

can you please elaborate the code flow for using this hack? as well I want to know this works for iOS and android device also?

The hack with CSS make the UI login a bit “broken” with a divider at top.
I found a better way to do it. Create 2 applications in your tenant in auth0 and redirect to the right one within your own web app. Authorize Google SSO only on one of the two applications.

The code below redirect a user browsing through Iphone to the application where SSO is disabled so that user won’t have the error pop (since this error occur only on iphones in my case). Look at user agent to make it match to your case ( detect mobile navigation).

if (navigator.userAgent.match(/iPhone/i)) {
    return process.env.REACT_APP_AUTH0_MOBILE_CLIENT_ID; // Google SSO is disabled
  } else {
    return process.env.REACT_APP_AUTH0_CLIENT_ID; // Google SSO is enabled
}

I have made the google sso integration, in that case also user need to authentication their google account in the embedded web views in iPhone. so, what is your snippet code meaning?
that is return process.env. REACT_APP_AUTH0_MOBILE_CLIENT_ID; and return process.env. REACT_APP_AUTH0_MOBILE_CLIENT_ID;
I have faced the problem now google oauth consent page is always open in the default WebView how can you restricted this, please tell me.

Noticing OpenAI managed to do Google Login in embedded browser. Not sure how they did it

For what its worth, I implemented this using Lock / Universal Login with the following changes to the javascript:

var allowedConnections = ['facebook', 'Username-Password-Authentication'];

var webViewRegexRules = [
  // if it says it's a webview, let's go with that
  'WebView',
  // iOS webview will be the same as safari but missing "Safari"
  '(iPhone|iPod|iPad)(?!.*Safari)',
  // Android Lollipop and Above: webview will be the same as native but it will contain "wv"
  // Android KitKat to Lollipop webview will put Version/X.X Chrome/{version}.0.0.0
  'Android.*(;\\s+wv|Version/\\d.\\d\\s+Chrome/\\d+(\\.0){3})',
  // old chrome android webview agent
  'Linux; U; Android'
];

var webViewRegExp = new RegExp('(' + webViewRegexRules.join('|') + ')', 'ig')

var isWebView =  !!window.navigator.userAgent.match(webViewRegExp);

if(!isWebView){
  allowedConnections.push('google-oauth2');
}

// Available Lock configuration options: https://auth0.com/docs/libraries/lock/v11/configuration
var lock = new Auth0Lock(config.clientID, config.auth0Domain, {
  allowedConnections: allowedConnections,
// Lots of other settings...
});

I used the WebView detection logic from this library: GitHub - atomantic/is-ua-webview: 📱tiny/simple npm module for detecting webview status of a user-agent

1 Like

@soumik.das the above code snippet is dynamically selecting a client ID for authentication based on whether the user is accessing the application from an iPhone or another device. Why am I looking for Iphone? Because in my case I know that a user is navigating within embedded browser if they have “iPhone” in user agent.
So, I put the above code snippet in a function called getClientId in my web app code. Then, I use it in Auth0Provider like that:

<Auth0Provider
      domain={domain}
      clientId={getClientId()}
      onRedirectCallback={onRedirectCallback}
      authorizationParams={{
        redirect_uri: window.location.origin,
        audience: audience
      }}
    >
      {children}
</Auth0Provider>

Let’s say I’m using an embedded browser then I’ll be redirect to auth0 application with ClientId REACT_APP_AUTH0_MOBILE_CLIENT_ID that HAS Google social connection DISABLED. This way, I won’t see the Google button on login page and thus I can’t trigger 403_disallowed_useragent error.

Seems like it’s not working anymore, tested today.
Best solution for now seems indeed to be hiding the social login buttons unfortunately.

Here is a solution if you are using a custom template for the universal login (like me).
Add some javascript & css to your template to hide the social connexion widget in webview :

Your “universal-login-template.html” file scaffold :

<!DOCTYPE html>
<html lang="{{ locale }}">
<head>
  {%- auth0:head -%}
  ...
  <style>
    ...
    
    /* Webview : remove Google login */
    .browser--webview .prompt-wrapper ._prompt-box-outer > div > div > div > form + div + div,
    .browser--webview .prompt-wrapper ._prompt-box-outer > div > div > div > form + div + div + div {
      display: none;
    }
  </style>
  <script>
    // Fix the issue with Google login error in webview.
    // @see https://community.auth0.com/t/403-disallowed-useragent-for-web-login-from-embedded-browsers/55074/15?u=quentin.fahrner
    document.addEventListener("DOMContentLoaded", function() {
      const webViewRegexRules = [
        'WebView',
        '(iPhone|iPod|iPad)(?!.*Safari)',
        'Android.*(;\\s+wv|Version/\\d.\\d\\s+Chrome/\\d+(\\.0){3})',
        'Linux; U; Android'
      ];

      const webViewRegExp = new RegExp('(' + webViewRegexRules.join('|') + ')', 'ig')
      const isWebView = !!window.navigator.userAgent.match(webViewRegExp);
      if (isWebView) {
        console.log(window.navigator.userAgent + ' - Browser is a webview, hiding social connexions')
        document.body.classList.add('browser--webview');
      } else {
        console.log(window.navigator.userAgent + ' - Browser is a regular one, showing social connexions')
        document.body.classList.add('browser--regular');
      }
    });
  </script>
  <title>{{ prompt.screen.texts.pageTitle }}</title>
</head>
<body class="_hide-prompt-logo">
  <div class="page-wrapper page-wrapper--{{ prompt.name }}">
    ...
    
      <div class="prompt-wrapper">
        {%- auth0:widget -%}
      </div>
    
    ...
  </div>
</body>
</html>

Then simply update the template :

PUT https://YOUR_AUTH0_DOMAIN/api/v2/branding/templates/universal-login
Content-Type: text/html
Authorization: Bearer ACCESS_TOKEN

< universal-login-template.html

Thanks @rgriffith !

1 Like

I’ve recently encountered an issue where some users reported being unable to complete their registration using Google login on my website after accessing the link through an app like LinkedIn. This only occurs on iOS. I’ve written a brief post explaining why this happens and how we can solve it. I hope you find it helpful: Solving Google Login Issues from LinkedIn's In-App Browser on iOS — felixcarmona

1 Like

This is actually a really good workaround. Best one so far.