I've used Firebase Auth to manage user logins on my app, and custom claims for their roles and permissions for each organization they belong to.
The problem is that when a user belongs to several organizations, the custom claims exceed the 1,000 characters length limit set by Firebase Authentication.
For the client, I can make an API call with the ID token, and respond with his/her claims. But for my gateway, it means I now need to query my database at each user request. It defeats the point of JWT at all.
How can I embed custom claims in a safe way?
Desktop Client: ReactJS + Firebase SDK
API Gateway: Express on NodeJS
Backend: Firestore for user metadata
Usually the keys and values of custom claims are very short, and you should not run into this limit. Short keys and values are important, since the claims are encoded in the JWT, which is sent with each request/connection.
You are likely storing readable, meaningful values in your token now. I'd recommend using shorter "codes" as the keys/values of your claims, similar to the three letter default properties of a JWT. That will keep your token size under control, and should bring you back under the limit unless really have a lot of claims.
Related
There's an open feature request for Metabase to support IAP. I took a stab at it, and have a Clojure implementation of the steps detailed in Securing your app with signed headers (i.e. verify token header, verify token payload, retrieve user identity).
But this question isn't necessarily specific to Metabase. The general idea is to replace Google Sign-In and only use only IAP signed headers for authentication and user creation in an application on Google App Engine (specifically, GAE flex environment).
The "problem" is that the user identity information from the IAP token looks like: {"email":"alice#example.com","sub":"accounts.google.com:118133858486581853996"}. I also came across Using special URLs, but this returns something like: {"email":"accounts.google.com:USER_EMAIL","sub":"accounts.google.com:118133858486581853996"}.
With a Google Sign-In token, I can obtain values for given_name and family_name along with email, which means I can fetch-or-create a valid Metabase user. Is there a way to get the first and last name via the JWT sub, (i.e. accounts.google.com:118133858486581853996)?
Hm, if they have a public profile you can pass the number after "accounts.google.com:" to https://developers.google.com/+/web/api/rest/latest/people/get . Unfortunately, you won't be able to authenticate to that API as the user, since IAP doesn't currently provide a way to call let users delegate access to call Google APIs. (You'll have to use a service account to call that API.)
The other solution would be, if IAP provided a way to a) specify additional scopes in its OAuth request to Google, and if it then b) passed additional claims from the OIDC token into the IAP JWT, you'd be able to configure IAP to request the "profile" scope. However, IAP currently only requests the "email" and "openid" scopes, and doesn't have a mechanism for specifying additional scopes.
-- Matthew, Google Cloud IAP engineering
firebase claims are used to control user permissions across firbase services like firestore rtdb storage .
I have 2 options
create-custom-tokens and firebase auth custom claims
is the claims in the custom-tokens are also limited to the same 1000 bytes size as the built-in option ??
can I just have an http trigger to the cloud function to create a custom token when needed from the frontend and use that token(that includes the custom claims) in any transaction that require user permission like upload a photo on a specific route. As the latest sdk allows to call the function without any boilerplate for HTTP client libraries is that feasible??
Claims on custom tokens are not size limited. But you can't exactly use custom tokens the way you've proposed. Only thing you can do with a custom token is to sign in with it on a client app: https://firebase.google.com/docs/auth/admin/create-custom-tokens#sign_in_using_custom_tokens_on_clients
However, once you perform the sign in, you can use the resulting ID token to perform any operation you need. That is the ID token will have the custom claims set on it.
My application have to fetch data from external services with the usage of manually provided at profile/management by user api key & api secret.
I'd like to prevent a huge amount of retriving those necessary keys queries to database and persist it somewhere else (assuming that those keys won't be updated too frequently).
From my point of view it could be implemented with next options:
Use MemoryCache provider with SlidingExpiration;
Create a custom Claim and append it into existing Identity claims collection;
Please correct me if I'm wrong, but if I've realized it right - claim's information is a part of data, which is used for serialization/deserialization at frontend<->backend interaction (I'm not quite confident about it, but suppose that it's used within cookies & tokens).
Actually these keys are also required for a several background processes (message queue consumers or scheduled jobs for example).
Would you mind letting me know a proper way for persiting such protected and frequently used fields in an optimized way?
Thank you in advance.
When you login using one of SignInManager's sign-in methods, it sets a cookie on the browser with an access token in it. This cookie contains claims data. So in subsequent authorized requests, you can query the User.Claims field to access the required fields without making a trip to your datastore.
Now whether you choose to use claims or not totally depends on how often you need the API Key / Secret. Your claims are part of the access token. If sending the API key / Secret on every request is justified, claims is the ideal choice.
UPDATE:
Rather than decrypting the tokens at the frontend, it's better to send them to the frontend client along with the access token.
Incase you're not aware of IdentityServer4 or OpenIddict do check them out. It's probably got all that you need.
I have 20 enpoints that HTTP POST to my realtime database using the query parameter "auth":"<db secret>" and this works but I need to restrict access based on group. There are 2 groups of 10 endpoints.
These (particle.io) endpoints can be hardcoded with the URL to POST to, query parameters, custom headers, etc, but I don't believe they can handle an HTTP response (get the token to use) without some additional firmware level coding.
Is it possible for me to manually mint a persistent (lifetime:0) token using the Firebase Admin SDK that I can then configure in my endpoint?
You can mint a custom token using Admin SDKs, but they are meant to be exchanged for an ID token, which is what you must present when accessing the Firebase database. Plus, both custom tokens and ID tokens are short-lived (1 hour TTL).
If possible, you can run the Admin SDK directly on your devices with its privileges restricted via database auth overrides. But this is not usually recommended, since the users on the device can simply disable that.
I think you will have to make some HTTP calls from your devices, if you're to make this work with access tokens.
Sometimes I want to send a message through Firebase notifications to one unique user, then I want access the token from that user, so I like to know what is the best practice for get that token at any time?
On initial startup of my app, the FCM SDK generates a registration token for the client app instance.
I can get that token, but if I save that token in Firebase realtime database, I think other people can access that data because it is "set persistent mode on" to access offline data.
My questions is:
Is it possible to get tokens of all users without save that in a database?
Can I get these tokens direct from Firebase Authentication? If not, what is the best practice for access these tokens?
I think other people can access that data because it is "set persistent mode on" to access offline data.
Simply save the registration token details to a secure node. Making sure that only you (or even including the user itself) to be the only ones that can access it. Read more on Understand Firebase Realtime Database Rules.
I can get that token, but if I save that token in Firebase realtime database, I think other people can access that data because it is "set persistent mode on" to access offline data.
Users won't be able to get the data they're not allowed to/wasn't designed to have on their device if you choose to restrict them.
Is it possible to get tokens of all users without save that in a database?
There is no API to get all the registration tokens related to your app. As mentioned in the documentation (emphasis mine):
After you've obtained the token, you can send it to your app server and store it using your preferred method. See the Instance ID API reference for full detail on the API.
It's the developer's (you) responsibility to send and store the registration token to a secure location.
Can I get these tokens direct from Firebase Authentication?
I'm not entirely sure what you mean by this. FCM Registration tokens are different from auth tokens. So, no.
If not, what is the best practice for access these tokens?
So long as you store the tokens in a secure location and make sure that you're always using the most recent/valid token, it should be good.