How should Firebase custom claims be added from App Engine? - google-app-engine

Using App Engine (Java) to add custom claims to a user's Firebase token as shown here. I'm using the Application Default Credentials as my project owner account. Running gcloud auth list shows that the correct account is active.
I've configured my Firebase settings in the app as follows:
// Error handling and try/catches omitted
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setProjectId("<my-app>")
.setDatabaseUrl("https://<my-app>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
Once this is set, I use the following code adapted from the example here.
Map<String, Object> claims = new HashMap<>();
claims.put("role", "admin");
fbInstance.setCustomUserClaims(usersFirebaseAccessToken, claims);
This throws the following error:
Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the identitytoolkit.googleapis.com. We recommend that most server applications use service accounts instead. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.
After seeing this, I reverted to the standard service account approach where instead of GoogleCredentials.getApplicationDefault(), I used ServiceAccountCredentials.fromStream(serviceAccountStream) where serviceAccountStream = new FileInputStream("path-to-service-account-file"). This complained about insufficient privileges despite having the Firebase Admin group in GCP IAM settings. The real issue, though, is that the Identity Toolkit docs here mention that the Identity Toolkit is being replaced by Firebase Authentication, which seemed to be the approach I was originally trying.
I'm interested to know what the error message above means by "end user". This seems to suggest that the GCP SDK is trying to authenticate as the user represented by the Firebase token but I'm almost certain this isn't what it means.
Is there something I'm missing in my Firebase config that's causing the system to think I'm the wrong user?

Related

Google Account IDs differ between OAuth2 and GoogleAppsEngine User API

I have problems replacing an old app because the IDs of Google Accounts differ between the different login options offered by Google.
Old app: Standard GoogleAppsEngine Java 8 Application using GAE User API
New app: Nest.js app deployed to CloudRun using Google OAuth2 via passport.js
I verified with many different emails (personal Gmail and GSuite) that both login methods return different Google User IDs - even if the documenation and other resources claim it's unqiue forever and accross login methods.
Obviously I would have expected that the Google Account IDs are independent of the login method.
Is there any way to match or migrate from the old to the new method?

Update existing Teams App to Multi-tenant failing during provisioning using Teams Toolkit

We have a Teams App which is created using Teams Toolkit - SSO Enabled Tab option.
This App is single tenant by default and we want to convert it to Multi Tenant.
We are following the steps mentioned in "https://github.com/OfficeDev/TeamsFx/wiki/Multi-tenancy-Support-for-Azure-AD-app" to do the same.
Here when I update the aad.template.json file and change the value of signInAudience to AzureADMultipleOrgs, and then run provisioning using teams toolkit. I get an error - "Failed to update application in Azure Active Directory. Please make sure 'templates/appPackage/aad.template.json' is valid: Request failed with status code 400 Detailed error: Request failed with status code 400. Reason: Values of identifierUris property must use a verified domain of the organization "
On changing the value back to AzureADMyOrg, provisioning is successful.
Anyone faced similar issue
It sounds like it's failing because you don't have a verified domain registered with Azure. It's only required for multi-tenant apps, but that's exactly what you're building. Essentially, you need to have a regular external domain registered with Azure, something like a .com, .io, .net, .whatever public domain.
On the page you linked, it actually says as much:
Since Azure AD app requires an "tenant verified domain" for Application ID URI, you can use your own Custom Domain or Create a new Custom Domain on Azure.
But this looks useful too: https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-modify-supported-accounts#why-changing-to-multi-tenant-can-fail
This error is because you are not using a verified domain in Application Id Uri of your multi-tenant Azure AD app. Teams Toolkit will by default use Storage to host your Tab app, however Storage endpoint is not a tenant verified domain, and thus you will fail with this error if only update your AAD manifest.
You can follow step 2-4 in Update your Tab applications to create your CDN or use your own tenant verified domain and setup the endpoint in your project.

How to use a Google service account on a Reactjs Firebase project for using APIs?

I am trying to integrate a Google service account to my reactjs-Firebase project but I seem to not understand how to do it.
What I have tried:
I selected JSON as my KEY type for the service account and downloaded it to my system and tried to set it using Application default credentials. (didn't work)
but nothing seems to work.
and I don't understand how to use the service account to call API in this react-firebase project.
am I supposed to authenticate it using Application default credentials or some other method.
Expected result: Want to integrate service account to my reactjs-firebase project so that I can call API's without an API key
Actual result: not able to do that.
Thank you for your help.
You should never put a service account embedded on your front-end or any other secrets as anyone using developer tools in browser can see them.
The best approach for you should be the end user providing their credentials that need to be authenticated against your backend. In the backend if the user is authorized you can have access the service account information and make the calls you need.
Specifically on your Firebase you should use the Cloud Secret Manager and access if like this:
const functions = require('firebase-functions');
const { defineSecret } = require('firebase-functions/params');
const serviceAccount = defineSecret('SERVICE_ACCOUNT_KEY');
// get other secrets and do whatever you need...
There is a tutorial here on secrets.
Or you can go straight to the documentation here.

Google AppEngine Datastore admin tool authentication error

When I try to open the google appengine datastore admin tool it redirects me to:
https://ah-builtin-python-bundle-dot-myapp.appspot.com/_ah/login_required?continue=https://ah-builtin-python-bundle-dot-myapp.appspot.com/_ah/datastore_admin%3Fapp_id%3Dmyappid
and gives me a 500 error.
According to this appengine bug report:
https://code.google.com/p/googleappengine/issues/detail?id=10150&q=%22datastore%20admin%22&colspec=ID%20Type%20Component%20Status%20Stars%20Summary%20Language%20Priority%20Owner%20Log
"This looks to be a problem because you are using non-default authentication scheme.
Are you using user service/Google Accounts API for authentication of users inside your application? If not, consider changing your authentication method.
If you are, then you'll need to setup a custom domain and access the datastore admin via:
https://ah-builtin-python-bundle-dot-
so that the correct authentication cookies can be used."
I'm using simpleauth for authentication and have a custom domain with an ssl certificate.
I would love to be able to backup my datastore data, it's a pretty big risk for my site if I can't!
Any ideas?
Must have been a problem on Googles end, because when I tried again a few months later it magically worked.

Google Endpoints: How does the IDE (or terminal) authentify to GAE when uploading code?

I am new to Google Endpoints and Datastore. I've followed several tutorials, among which this one for example: https://github.com/GoogleCloudPlatform/endpoints-codelab-android
My question is: what is the security mechanism that is used when we deploy the Endpoints backend application to Google App Engine? How does Google App Engine know you are the owner of the project? And I have this same question both for deployment through a terminal (See Step 6 of above tutorial) and for deployment through an IDE (e.g. through Maven in Eclipse).
I imagine that somehow the terminal (or the IDE) gets your credentials from the browser, which is logged in to the GAE console but I am not sure at all this is the good explanation.
Thanks! :-)
There are several ways to authenticate when deploying to Google App Engine. The recommended method uses OAuth2 to authenticate with Google (see below for another method). OAuth2 is the method used in the tutorial you mentioned (search for oauth in the link you sent), and is activated by the setting
appcfg {
oauth2 = true
}
in the build.gradle file of that tutorial. If you prefer the command-line appcfg interface, use the flag appcfg --oauth2.
When you installed the Google Cloud SDK, you were shown a web page in which you authorized the SDK to access and modify various Google Cloud services, including App Engine. The SDK locally stores a token which indicates that it is allowed to deploy to App Engine under your username. The oauth2 = true line tells appcfg to request access to App Engine using this token.
If you like, you can view (and revoke) this authorization by navigating to Google's Account Permissions page. You should see an entry for Google Cloud SDK, and clicking on it will show you that the SDK is authorized to access App Engine. If you click on "Revoke", the locally stored token will no longer be valid and you will need to re-authorize in order to use most of the Cloud SDK functionality.
If for some reason you do not want to rely on oauth2 (for example, if for security reasons you want to enter a password every time you deploy), then you can remove the oauth2 = true line (or the --oauth2 command-line argument). This will cause appcfg to prompt for your Google username and password each time you deploy. However, this is a lot less convenient, both because appcfg will not store your password, and because it does not support 2-factor authentication. So, if your Google account uses 2-factor authentication (which is really recommended), you will need to use an App Password with this approach.

Resources