Auth0 React JS Quickstart Not Requesting all scopes - oauth-2.0

I am currently using the react JS quick start available at the following link.
https://github.com/auth0-samples/auth0-react-samples/tree/master/Sample-01
About a year ago, I was able to repurpose it. That old app is still working fine, able to authenticate, authorize and also make calls to a custom API.
On the old app, I am getting all the scopes.
“scope”: “openid profile email read:profiledetails read:seeallquotes read:sitestats read:testperm1 read:testperm2”
Now, I have made a fresh copy of the react app using the quick start option, from the same auth dashboard as the old app. Updating the config file to match the old app config files. I get the following scopes
“scope”: “openid profile email”
Why am I not getting all the scopes as per the user login? Same user, on the old app, gets all the scopes. I believe, the new react app is not asking for all the scopes when it asks for token. But, I have updated all the scopes I need in the auth config.
Both apps - old and new - have the exact same auth file, and are linked to the same auth0 server, same custom api, same everything. I am also using the same user account for testing on both the apps.
{
“domain”: “removedonpurpose.us.auth0.com”,
“clientId”: “removedonpurpose”,
“audience”: “removedonpurpose”,
“scope”: “read:current_user update:current_user_metadata read:capquotes read:penquotes read:profiledetails read:seeallquotes read:sitestats read:testperm1 read:testperm2”
}
Why is this happening?
What else should be included in the react app to make it ask for all the scopes?
This question is related to the original question I posted on the Auth0 forums. Linking it here. https://community.auth0.com/t/scope-not-included-in-token-call/65173

Right after I posted this I discovered that the latest version of the react quick start makes some changes.
especially the following.
// Please see https://auth0.github.io/auth0-react/interfaces/auth0provideroptions.html
// for a full list of the available properties on the provider
// const config = getConfig();
// const providerConfig = {
// domain: config.domain,
// clientId: config.clientId,
// ...(config.audience ? { audience: config.audience } : null),
// redirectUri: window.location.origin,
// onRedirectCallback,
// };
I missed this part. in the old app, the configuration was done differently. It looked something like this.
<Auth0Provider
domain={config.domain}
clientId={config.clientId}
audience={config.audience}
redirectUri={window.location.origin}
onRedirectCallback={onRedirectCallback}
scope={config.scope}
>
<App />
</Auth0Provider>,
with the settings read directly from JSON.
Anyway, I went back to the old way for now. The quick start tutorial still shows the old options which threw me off as I was using the tutorial as reference and did not discover that they made changes.
Not blaming the tutorial. I should have investigated in the beginning.

Related

Flutter Auth on iOS hangs when retrieving token with code exchange

I have the following code in flutter trying to retrieve an oauth2 token via auth code with PKCE flow:
final FlutterAppAuth appAuth = FlutterAppAuth();
final request = AuthorizationTokenRequest(
B2C_CLIENT_ID,
B2C_REDIRECT_URI,
discoveryUrl: 'https://$B2C_DOMAIN/.well-known/openid-configuration',
scopes: ['openid', 'profile', 'offline_access'],
// promptValues: ['login']
);
final AuthorizationTokenResponse result =
await appAuth.authorizeAndExchangeCode(request);
When this code is run in iOS, the browser opens and I can see it tries to load the signin page, but then immediately closes. No exceptions are thrown or anything. The code basically hangs at appAuth.authorizeAndExchangeCode almost like it doesn't know that the browser has closed.
I am not sure what could be causing this.
The code correctly determines the url for showing credentials using the discoveryUrl (i.e. it makes the http request first using the discoveryUrl) but not sure why it basically hangs after.
I am using azureb2c for authentication here.
Edit
Ok turns out this is a problem with using azure b2c in particular as tried it with a different identity provider and works fine.
I managed to locate the issue and fix it now a login page shows in the browser. After entering credentials, browser closes, but code still hangs on appAuth.authorizeAndExchangeCode(request); and does not proceed.
Also found existing issue. on github: https://github.com/MaikuB/flutter_appauth/issues/182
I managed to solve this following the below answer on the Github repository of the flutter_appauth plugin.
https://github.com/MaikuB/flutter_appauth/issues/182#issuecomment-840707729
Eventually, all I had to do was to add a trailing slash to the redirect url parameter in AuthorizationTokenRequest.
(It looks like Azure AD appends on a trailing slash to the redirect url which causes the validation in AppAuth to fail).
My app worked correctly with the slash both on Android and iOS.
P.S. If this doesn't work for someone, try to adjust the redirect url in your App Registration as suggested in the respective thread https://github.com/MaikuB/flutter_appauth/issues/223.
I suspect this is related to the call to resumeExternalUserAgentFlow, so here is a plan of action for you:
Follow the steps in my blog post to get the AppAuth Swift + Carthage sample working - which also uses a Private URI Scheme. Use my online configuration details as specified in the blog post and you should have a working solution. I have just verified that my instructions still work.
Update the same sample to use your Azure AD configuration and see if it still works. If so then there is nothing wrong with AppAuth and the problem is in the Flutter layer.
If the Swift sample fails when you update to Azure AD configuration, add some print messages for the URL being supplied to resumeExternalUserAgentFlow in the AppDelegate class, and see if this is different to the original redirect URI. If the redirect URIs are different, reset to the original value and hopefully that will resolve things.

Why is my Google OAuth2 Sign in working, disregarding of my apps signing keystore

In our app we are using the Google Drive REST API. To authenticate, we're using Xamarin.Auth with the following configuration
var authenticator = new OAuth2Authenticator(<our client ID>,
null,
"https://www.googleapis.com/auth/drive",
"https://accounts.google.com/o/oauth2/v2/auth",
<our redirect url>,
"https://www.googleapis.com/oauth2/v4/token",
null,
true);
The login is presented using
var loginPresenter = new OAuthLoginPresenter();
loginPresenter.Login(authenticator);
(this is not the actual code, since the authorization is encapsulated in a class and the authenticator and the presenter are injected, but basically this is what we're doing).
This will open a login form in a browser and allow the user to login, resulting in the form calling back our app with a OAuth2 token. Everything works like a charm.
Our client ID has been created using the hash of our debug keystore. According to the docs and other questions (see here and here), this should cease to work in release configurations when the app is signed with a different keystore. Anyway, having signed the app with our internal testing AdHoc keystore, the login form still works without any issues. Actually I do not see how it should not. After all, all we do is opening a website in a system browser control, hence I do not understand how the website is supposed to get our apps hash.
Since the linked questions lack details, I can't see how they are different to our situation, but I somehow assumed Google OAuth to do some black magic to ensure that the hash matches. Is there any reason that this works for us? Can we expect it to keep working after it's been uploaded to Google Play or is there any risk that it stops working?

Google 400 Error: invalid request Custom scheme URIs are not allowed for 'Web' client type

When I am signing into Gmail in my iOS App, I am getting the below error (screenshot) and the sign-in fields do not appear. We are loading the sign-in screen in a WKWebView.
We are using a custom URI redirect but why is google throwing this error now. What are the alternatives to a custom URI?
Swift 2.3 project
Using OAuthSwift v0.6.0 cocoapod
This started quite recently only in the past week or so I believe something changed with Google's APIs.
I have read that google is deprecating webviews for OAuth and will block requests on April 20, 2017. As seen here in a Google Developers Blog:
https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html
Does this mean I already need to use or is there another viable solution? I thought I had more time before needing to update this.
My guess is that your client is registered incorrectly in Google Cloud Console. A 'WEB' client is typically a server or Javascript application. An iOS app should be registered as an iOS client.
https://developers.google.com/identity/protocols/OAuth2InstalledApp#creatingcred
I Just found this problem too.
Please check google developer console and look at the credentials keys
Your Client ID in google-info plist must come from iOS application, not the web.
And use that Client ID to be revereseClientID and copy it in to URI type
I have solved the problems by create project in Fire Base Because REVERSED_CLIENT_ID generate from developers.google.com Incorrect.
Try create your project in FireBase
https://console.firebase.google.com
you must cross check clientId at your 'Google Dashboard' clientId and clientId at "GoogleProject.Plsit".if both are different, copy ClientID from 'Google Dashboard' and paste it on "GoogleService-Info.Plsit".and also amend your reverseClientId in "GoogleService-Info.Plsit" according to newly pasted ClientID(you check the pattern how reverseClientId created from client Id in "GoogleService-Info.Plsit"). And then paste thid reverseClientId in 'URL type' in your project setting.
In case of mine clientId on "GoogleService-Info.Plsit" and my 'Google Dashboard' were different.
chech your google dashboard here : https://console.developers.google.com/apis/credentials?project=firebase
I just experienced this issue following the Google Signin for iOS Guide. The plist generated file is not the good one. You need to take a look at the clientID and reversedClientID and be sure that they are the ones for the iOS app on your Google developer portal.
I faced this error after previously creating a GoogleService-Info.plist file using the site Google Sign In directs you to. I later started using Firebase, which seems to create a separate .plist file. After attempting to include Firebase's new .plist file, my Google Sign In button started yielding the invalid_request error with the Custom scheme URIs are not allowed for WEB client type message.
In order to fix the problem I tried many things, but in the end deleting MY ENTIRE Firebase project on their web console (not just the individual app), recreating a new Firebase project from scratch, and re-downloading the new .plist file, solved the error.
It creates two client ID. one for web and one for iOS application. Web client will be in the google plist by default. So it gives the above error. Use iOS Client id from google console or create credential for iOS application.
For my experience, I had followed Google's SignIn iOS Swift guide and had downloaded a Web OAuth JSON file. They literally provide you the wrong Plist file for an iOS setup.
Just in case somebody else runs into this issue here are the steps I followed:
Go to the Google Developers console.
Go to the Credentials section.
Notice there are two items in the "OAuth 2.0 client IDs" section. (If you previously attempted to configure an iOS Google SignIn project.
Click on the name of the "iOS client for ".
Click "Download PLIST File".
Delete the Google web Plist file from your project.
Drop in the new iOS based Plist file.
Copy over the new REVERSED_CLIENT_ID into your URL Types of the Info page of your project. (This is detailed in Google's guide).
Attempt to run your app again.
Note: I got the Google Sign In API to work with Swift v3 and XCode v8.
I was getting the same error. Then I figured out, that I did not provide my app Bundle Id to access the Google Sign In Service in my app.
You do that from the page with the link:
https://developers.google.com/mobile/add?platform=ios&cntapi=signin&cnturl=https:%2F%2Fdevelopers.google.com%2Fidentity%2Fsign-in%2Fios%2Fsign-in%3Fconfigured%3Dtrue&cntlbl=Continue%20Adding%20Sign-In
1.Sign in with your Google Developer account.
2.Create you app name and copy the App bundle Id from your project from:
Project and Target List> General> Bundle Identifier.
3.Choose your Country
4.Enable Google- Sign In.
Then perform the necessary steps to integrate Google Sign In in with your iOS App.
I was facing the same issue. I followed all the instructions to integrate my app several times, and played with the code to see if there was any hidden issue in the code.
I downloaded and configured the sample app from google at github https://github.com/googlesamples/google-services and go the same issue, so it was not the code.
It seemed like there is something in my console configuration so I switched between different google console apps, and played changing the bundle IDs.
The only thing that managed to fix this issue was to use Firebase instead. I created an app in the firebase console, downloaded the new plist, and it worked.
Still not sure why this didn't work for me in the first place, this doesn't seem to be a common problem, but I hope this helps someone.
cheers,
Kindly check console.developers.google.com/apis/credentials for your project and see whether there is already a client_id in OAuth 2.0 client IDs section , if so then copy that client id and replace it with you GoogleService-Info.plist file's CLIENT_ID and accordingly change REVERSED_CLIENT_ID (in reverse manner) now clean and build your app and test it will work
I was using Meteor with Cordova and Meteor's official google integration, which relies on cordova-plugin-googleplus.
I had to:
create both an iOS and a web Client ID
use the web Client ID on the settings / server / database as documented
but then use the reverse of the iOS web client as the REVERSED_CLIENT_ID for cordova-plugin-googleplus
Expo, authentication with Google.logInAsync from expo-google-app-auth
In my case I just used androidClientId instead of androidStandaloneAppClientId

Remember App-Engine Sign-In on IOS Devices

I've been following this Google page that describes how to authenticate under IOS to an App-Engine (cloud endpoint) backend. That's fine. However, it seems to require signing in anew with each run of my program.
Is there any way to
skip the signin/authentication web-view in favor of some global resource,
remember previous signin/authentication information and re-use it, or
simplify the signin/authentication procedure by remembering the previous username
It would be nice if the IOS version could behave like the Android version which, of course, does not need a sign-in step because it's handled directly by the OS.
Thanks!
I've now worked this out. Not sure how I missed it in the documentation during my first pass.
See "Retrieving Authorization from the Keychain" at https://code.google.com/p/gtm-oauth2/wiki/Introduction
GTMOAuth2Authentication* auth =
[GTMOAuth2ViewControllerTouch
authForGoogleFromKeychainForName:AUTH_KEYCHAIN_NAME
clientID:IOS_CLIENT_ID
clientSecret:IOS_CLIENT_SECRET];
if ([auth canAuthorize]) {
// add existing auth to our GTLServiceFoo, cleverly named "fooEndpoint"
[fooEndpoint setAuthorizer:auth];
} else {
// go through sign-in dialog flow and add the auth resulting from that
...
}

YouTube API broken by Google. 'Authentication with Google failed. Reason: NoLinkedYouTubeAccount'

** UPDATE **
It truly seems that Google has just screwed every single person on the planet by absolutely requiring user interaction to upload a video. Of course I know, they are free. Exactly what I warned the client years ago about, so I don't need to be reminded. Thank You.
So I would like to try to take this in a different direction and just find a loophole and a workaround to still keep doing what we are doing in spite of Google's complete lack of support or caring in any way about the developers and what they have to deal with.
It would be different if you can actually call a phone number and talk to a human being about YouTube Partner access, but you can more quickly get access to the Illuminati.
OAuth 2.0 is now the only supported authentication method period. It does require user interaction.
But what about that token? Does anybody know how long the token lasts?
If I can obtain a token just once using user interaction and place it in the database, I can automate possibly hundreds or thousands of interactions afterwards.
In other words, I'm trying to turn the user interaction into a speed bump instead of a concrete wall.
If anybody has any examples of obtaining that token, caching it, and using it afterwards, that would be a godsend to me right now.
Thanks for the comments and the help. I'm not surprised that the YouTube Developers Forum just folded and said to come here instead :)
It seems that Google has completely pulled the plug on the existing dashboard.
https://code.google.com/apis/youtube/dashboard/gwt/index.html
That link is now 404'd. Tried from several different browsers on different systems.
Registered under the new Google APIs Console already, but still get the problem.
// Set the authentication URL for this connection object
$authenticationURL= 'https://www.google.com/youtube/accounts/ClientLogin';
// Try to connect to YouTube with the channel credentials passed
try {
$httpClient =
Zend_Gdata_ClientLogin::getHttpClient(
$username = $channelfields['EMAIL_ADDRESS'],
$password = $channelfields['PASSCODE'],
$service = 'youtube',
$client = null,
$source = 'Redacted Data',
$loginToken = $channelfields['CACHED_TOKEN'],
$loginCaptcha = '',
$authenticationURL);
} catch (Zend_Gdata_App_HttpException $httpException) {
$update_error['response_body'] = $httpException->getRawResponseBody();
$update_error['error'] = 1;
} catch (Zend_Gdata_App_Exception $e) {
$update_error['message'] = $e->getMessage();
$update_error['error'] = 1;
}
This code has worked perfectly fine before, but does not work with the older API key, or the newer one generated inside the Google APIs console.
I'm attempting a simple upload and this concerns me greatly:
"The service account flow supports server-to-server interactions that do not access user information. However, the YouTube Data API does not support this flow. Since there is no way to link a Service Account to a YouTube account, attempts to authorize requests with this flow will generate a NoLinkedYouTubeAccount error."
From all reports it seems that Google has forced YouTube uploads to become interactive in all cases precluding all possibility of platforms that automatically upload generated content from working at all.
Any help or insights into the process is appreciated.
P.S - Ohhh, it's been awhile since I looked at that system and Google shut down the YouTube Developer Forums and said "YOU" were responsible for their support now :)
OAuth2 does support the ability to avoid user interaction through the offline access type parameter (ie, using access_type=offline). Check out Google documentation for details.
The solution is really rather simple. Your app needs to use oauth to request offline access. It will be given an access cide which you convert to a refresh token, which is the thing you store in your database. This doesn't expire. Well actually it sometimes does, but that's another story. Whenever you need to access the api, use the stored refresh token to request an access token which you include in each api call.
See https://developers.google.com/accounts/docs/OAuth2WebServer for details.
I don't know what you did but https://code.google.com/apis/youtube/dashboard/gwt/index.html works perfectly fine for me. Maybe it was a temporary issue. If you want no user interaction you HAVE to use YouTube API v2 OR you have to use v3 with methods that don't require authentification OR you have to provide your own youtube account credentials which is not recommended and probably not appropriate for you situation.
Several issues to respond here, I think.
1) The older API console has not been removed, but I've noticed intermittent outages to it and to the newer API console while Google is rolling out their new "cloud console."
2) ClientLogin was officially deprecated in April of 2012, not just 48 hours ago. Jeff Posnick has detailed all the changes over the months (and related ones, such as AuthSub, Youtube Direct, etc.) at his blog (apiblog.youtube.com).
3) You're right that, with v3 of the APIs, you cannot do automatic uploads across the board, as the oAuth2 flow requires user interaction. However, given the limited description of your use case, using refresh tokens is probably your best bet. If the content is user generated, somewhere they must be logging into your app, correct? (so that your app knows which credentials to leverage to do the uploads). At the point they're logging into your app, and you're starting the oAuth2 flow, you just have to hit the first oAuth endpoint and pass it the parameter access_type=offline (along with any other parameters). This will ensure that, when they grant that initial permission, you're returned a refresh token instead of an access token. With that refresh token, you can exchange it for multiple access tokens as needed (an access token lives for about an hour. I don't know how long a refresh token lives, but I've never had one expire before my own login cookies did, and then I just get a new one when my users re-login to my app).
Here's some more info on how to use the refresh token; note, too, that the various google api client libraries make it pretty smooth.
https://developers.google.com/accounts/docs/OAuth2WebServer#refresh
Also, this video tutorial from a Google Developers Live broadcast a couple of months ago might help illustrate the point: http://www.youtube.com/watch?v=hfWe1gPCnzc -- it's using the oAuth playground rather than a client library, but the concept is the same.
The answer is to use google-api-php-client, create an interactive auth page, and set up YouTube API v3 correctly with the new API console.
You can create a very simple page that will authenticate for the supplied channel and then store the correct token in your database. Is already working and uploading hundreds of videos on one channel. You do need to remember to fully activate yourself under the new API console and add the services required. Just keep authenticating and adding the services it says it needs. After that, the regular v3 upload process works just fine. On failure send a group an email and they can get a new token in 10 seconds.
Not the most elegant solution, but the documentation from Google is far from elegant anyways that Stack Overflow is now their front line support.
Just hang in there, a solution is always found. Don't give up!
I didn't get here by myself either, the other answers on this page helped me get all the way to this point. Thanks guys.
P.S - Don't forget the scopes
$client->setScopes("https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload");

Resources