Using Firebase OpenID Connect provider as Azure Function App Identity Provider - firebase

I have a react-native app that handles authentication using Firebase. That works great
The app calls serverless functions in Azure which id like to add authentication to by selecting an identity provider.
Azure Function App Identity Provider Options
Ive tried using OpenID Connect with the following configuration values but had no luck
metadata url: https://securetoken.google.com/{my-project-id}/.well-known/openid-configuration
client id: 412-3gp*******************.apps.googleusercontent.com
client secret: taken from the link below
https://console.cloud.google.com/apis/credentials?authuser=1&project={my-project-id}&supportedpurview=project
Firebase OpenId configuration
Process:
Get idToken from the already-authenticated Firebase user in my app
Pass that (jwt)idToken as a Bearer authentication header when calling my Azure function
Result:
401 unauthorised response
No response body is present
Expected result:
200 response
Does anyone know if its possible to use Firebase as an OpenId identity provider and if so, where I should get the correct ClientId and Client secret values from?
I notice the are some value in the Firebase console and also some in the Google cloud console

I've been facing exactly the same issue this morning and managed to get it working.
I initially did the same as you and set the client ID to be xxxxxxxx.apps.googleusercontent.com. That client ID value came from the same page you have liked to above for the client secret. Those values still resulted in the 401 error.
When I changed the client ID to be the Firebase project ID it all started working as expected.

Related

Firebase refresh token usage in backend

I have 2 app (Provider and Client). I have added Firebase auth to Provider app. I register in Provider app and save Provider's information in firebase and also its some information in my server(refreshToken, pairing code, providerID)
In Client app I write Provider's pairing code for matching with provider (checking this pair code has or not in my server). If client's login success I get refreshtoken and login in firebase with token.
The reason I save refresh token in my server I want to change some info in Firebase from Client app and create auth between client app and server.
The question I searched in google and I see this way is insecure that saving user's refresh token in database.
Is this way is secure?
How I create this flow?
When I disable account in firebase auth list, refresh token works still

Should the JWT from Firebase be the same as running "gcloud auth print-identity-token"?

I have a Cloud Run app that is not open to public traffic. It requires authorized traffic.
I obtain the JWT from a Firebase sign-in flow. I obtain the JWT after signing in using an account and then running firebase.auth().currentUser.getIdToken() to get a JWT.
With that same account, running gcloud auth print-identity-token on my machine, I get a different JWT than above.
I use a get request with the Authorization header to my Cloud Run application. This account mentioned (which is the same in either case) has an Owner role within IAM for this project. Therefore, there should be sufficient privileges.
In the cases I have described above, the first example returns a forbidden 401 Unauthorized response from my Cloud Run application. The second example, works correctly and returns a response.
Why do I get different JWT for the same account? Why does one of these methods work and the other doesn't--they are the same accounts?

Azure AD B2C with ASP.NET Web API issue token for both authentication in Web API and accessing MS Graph API

I'm new to ASP.NET and Azure AD B2C in general. My goal is to create ASP.NET 5 application which will be accessible through react-frontend with MSAL library. On frontend I have successfully issued both access and id tokens to authorize in my application without any problem, and they are accepted by ASP.NET backend and authorize user requests. I've encountered problem as soon as I tried to access user in current context of request on Back-end. This token does not simply allow me to call MS Graph API https://graph.microsoft.com/v1.0/me with token that I get, to get data about user. The error I get is
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Invalid x5t claim.",
"innerError": {
"date": "2021-11-29T15:48:41",
"request-id": "91b63eeb-0346-4ab2-9d31-ca58e8d1e30b",
"client-request-id": "91b63eeb-0346-4ab2-9d31-ca58e8d1e30b"
}
}
}
After additional research I found out that tokens that are used for authentication for Back-End are not usable for retrieval of user data from AD B2C or Graph API, since currently AD B2C does not support "on-behalf-of" flow.
How can I implement authentication flow where I still use AD B2C as authentication provider and user data provider for my application ? Additionally, in future, I want enable users to store their own secrets in Azure Key Vault, which can be done only, as far as I understood, via Graph API.
You can secure your app and API using the B2C tokens, then have the API itself generate its own token to access Graph API. The MS Docs have instructions for how to set your app up to get access without a user.
In your case your app would take the user's ID from the user-specific access token it was passed, then use it's own access token to make a call to https://graph.microsoft.com/v1.0/users/<useridfromtoken> to get the user's details.
If the information you need is stored in the B2C directory but not returned in the token, and you don't want to give your app access to the entire directory via Graph, then another option is to implement a userinfo endpoint.
If you want users to store secrets in Key Vault (assuming this is some function of your API) then you need to be looking at the .NET Key Vault secret client library.

Firebase Admin SDK - How to initialize with OAuth2 Refresh Token and communicate securely with web app?

I'm developing a web app (using Angular) which works with Firebase.
I installed the ngx-auth-firebaseui which is an easy to use library I used to perform user login. Since I need custom APIs I also developed an ExpressJs server that uses the Firebase Admin SDK.
I call ExpressJs APIs without any security for now (since I'm still in my local environment).
In order to use the Firebase Admin SDK, I followed the official docs, which say:
Once you have created a Firebase project, you can initialize the SDK with an authorization strategy that combines your service account file together with Google Application Default Credentials.
Firebase projects support Google service accounts, which you can use to call Firebase server APIs from your app server or trusted environment. If you're developing code locally or deploying your application on-premises, you can use credentials obtained via this service account to authorize server requests.
[...]
When authorizing via a service account, you have two choices for providing the credentials to your application. You can either set the GOOGLE_APPLICATION_CREDENTIALS environment variable, or you can explicitly pass the path to the service account key in code. The first option is more secure and is strongly recommended.
Locally I set the GOOGLE_APPLICATION_CREDENTIALS property and everything is okay. Does this also need to be set in the production environment or is there another method?
I would also like to use OAuth2 to secure communication between the web app and the server APIs, but I don't know how to integrate it within the authentication flow.
In addition, Firebase docs state:
The Admin SDKs also provide a credential which allows you to authenticate with a Google OAuth2 refresh token:
var refreshToken; // Get refresh token from OAuth2 flow
admin.initializeApp({
credential: admin.credential.refreshToken(refreshToken),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});
but if I do this I receive the error:
.../node_modules/firebase-admin/lib/auth/credential.js:47
var tmp = from[key] || from[alt];
^
TypeError: Cannot read property 'clientId' of undefined
Question 1: Fireabase Admin SDK initialization -- How to handle locally vs. in production?
Answer: Using the Firebase Admin SDK requires initialization in the local development environment as well as the production server environment. In both environments, you may either set the GOOGLE_APPLICATION_CREDENTIALS environment variable, or you may explicitly pass the path to the service account key in code.
Question 2: How to use OAuth2 for secure communications between Wep App and Server APIs?
Answer: Verify Id Tokens
After a successful sign-in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in this way to securely identify the currently signed-in user on your server.
Question 3: How to authenticate with a Google OAuth2 refresh token using the Firebase Admin SDK?
Answer from Manage User Sessions
Firebase Authentication sessions are long lived. Every time a user
signs in, the user credentials are sent to the Firebase Authentication
backend and exchanged for a Firebase ID token (a JWT) and refresh
token.
On the client (web app), the Firebase User has a refreshToken property to retrieve the current refresh token.
However, the standard approach to initialize the Admin SDK is to either set the GOOGLE_APPLICATION_CREDENTIALS environment variable or explicitly pass the path to the service account key in code.

How to authenticate a Firebase user to an IFTTT service?

I'm trying to build an IFTTT service and connect it to my Firebase backend.
I need to authenticate user as indicated in the IFTTT docs:
https://platform.ifttt.com/docs/api_reference#service-authentication
IFTTT’s protocol supports OAuth2 authentication, including support for
refresh tokens if so desired.
Your service API should use access tokens for authentication and as a
source of identity. A single access token should correspond to a
single user account or resource owner on your service.
If refresh tokens are used, they must be non-expiring. If refresh
tokens are not used, access tokens must be non-expiring.
But I can only get short-lived access tokens from Firebase it seems. Where can I get or how can I generate such tokens from the Firebase auth SDK?
Update in response to #FrankvanPuffelen:
I'll create an IFTTT service running on a Node server (possibly simply Cloud Functions) that will use the Firebase RTDB to send formatted HTTP request back to IFTTT. IFTTT requires me to authorize user accounts. Their required UX is something like this:
If an IFTTT user tries to use my service on the IFTTT website,
an auth dialog for my service pops up.
The user logs in and confirms IFTTT's access to their data on my service.
Some OAuth 2.0 tokens are exchanged.
IFTTT servers will periodically send requests (authentified with those tokens) on behalf of the user to my server.
Part of the question is: Can I use the Firebase Auth API to get those tokens, etc. or do I need to create a new OAuth 2.0 "layer" with my own generated tokens for IFTTT?
PS: I'm very new to OAuth, so it's all a bit confusing to me, sorry if the question isn't very clear.
So IFTTT calls Cloud Functions, which then calls Realtime Database, and you want to authentication the IFTT user with Realtime Database. Is that correct? If so, you can either use an OAuth2 token or create a Firebase Authentication session cookie.
Use an OAuth2 token
I did this not too long ago for accessing the Realtime Database from Google Apps Script. The requirements are relatively simple (once you know them):
The OAuth2 tokens must be requested with the correct scopes: https://www.googleapis.com/auth/userinfo.email and https://www.googleapis.com/auth/firebase.database.
The OAuth2 access token must be present in the request to Realtime Database.
The authenticated user must be at least an editor on the Firebase project. Note that this is not a Firebase Authentication user, but a Google user account.
Also see:
How to integrate Firebase into Google Apps Script without using (deprecated) database secret
Use a Firebase Authentication session cookie
You can also use a Firebase Authentication session cookie, which can be longer-lived (up to 2 weeks) than a regular Firebase Authentication ID token (up to an hour). You'll want to set up a Cloud Function for creating the session cookie, call that from IFTTT, and then pass the session cookie with the IFTTT request and along to the Realtime Database.
For more on this, see:
the Firebase documentation on managing session cookies.
I'm posting my solution here, this is a rough draft of what I did at at the time.
I'm using this auth method: My API has users with non-expiring OAuth2 access tokens and have an Express server responding at a Firebase HTTPS Cloud Function endpoint. Currently, at the prototyping stage, it generates fake tokens from the UID that are successfully accepted by IFTTT.
It's a redirect-heavy authentification flow based on this old IFTTT api example: https://github.com/IFTTT/connect_with_ifttt_auth_sample
Here's the gist of it:
Tokens and Auth Codes are just randomized and encrypted UIDs for now.
/oauth/authorize redirects to my app.
The app asks the user if they want to authorize IFTTT
The app redirects to /oauth/authorize_user
/oauth/authorize_user generates a user-specific code and redirects the user to IFTTT with this code
IFTTT asks /oauth/token to exchange the code for a Bearer tokens.
IFTTT can now make requests on behalf of this user with this bearer token.
Sample code here: https://gist.github.com/nathanvogel/15ed311258b91d7ec3d25f44047780e2

Resources