Firebase Auth JWT IDToken: is server side verification always needed? - firebase

I'm using Firebase Auth for user sessions.
ID Token is stored client side, and sent on every request to my GAE back end.
It seems costly, so I want to avoid it if I can.
I suppose I don't need to verify it for public-facing GET (idempotent) endpoints, but for access-restricted requests and POST requests, do I always need to verify the token with each request, or is there a safe optimization like caching the verified ID tokens serverside?

Example :
/get/account/user1
When redirect in it, send it and verify it.
But ! if you're going on /home, if you don't need an authentification, it's not necessary to send it.
Even more, I'll recommand to not send it when not needed.
If you've got a router, you should use some kind of Array with all routes which required your TOKEN ID and check the redirection :).

Related

Social Login with OpenID Connect - How to validate on the rest api?

My current setup is the following:
Single Page Application with Vue
Rest Backend
The SPA has social login functionality. It uses the authorization code flow with PKCE to retrieve:
Access Token / Refresh Token
ID-Token
As it is an SPA, the information is stored in local storage and therefore not 100% secure.
But how do I use this information to actually authenticate against my rest backend? The rest backend actually contains the user data I need after all.
Originally, I thought I could just send my access token or id token to my backend and the backend uses this as proof that I'm the correct user.
Main problems I see:
Make sure the access token / id token is actually from my application (the SPA)
Be protected if the tokens are stolen / Minimize the impact of this
For the first problem, the client_id might help, which is embedded in the id-token. It is kind of public information (because it is an SPA) and there is no client_secret. But the redirect_uri is specific to my SPA. Is this enough protection?
If it is my backend could have a list of allowed client ids and providers and check if the client id of the token is one of them.
The second problem is the lifetime of the token. Access tokens are only valid for a short time period and refresh token should be rotated. So it's kind of okay to store these in local storage. But the id_token is valid for a longer time. What do to about this?
Is this in general the right track? Or is my approach completely wrong?

What happens in case where someone steals your firebase auth refresh token?

I am starting to learn about JWT and I was wondering if some one got a hold of both my id token and refresh token, could that someone access firestore or other firebase resources pretending to be me indefinitely(until the refresh token is revoked)?
If so, how does firebase prevent this from happening?
I can't help feeling that the if someone could get my id token, it's not that hard to access the refresh token as well.
All communication with Firebase APIs are over HTTPS, which means that no one can listen in on that communication. It is secure. If someone got both a fresh ID token and a refresh token, then could impersonate you when making calls to Firebase APIs.
However, no one can get your ID token or refresh token unless you make a security mistake. For example, leaving your computer unlocked while you're signed in would be a bad idea. Or, having a password that's easy to guess. Use all the standard security precautions, and you won't have a problem.

How are authorization tokens stored / recreated by the browser?

I am Looking at the Network activity of this page: https://helm.csod.com/ux/ats/careersite/4/home?c=helm&lang=de-DE.
Specifically at the post request with the Name: "search". Its using an authorization token.
tldr: How is the following authorization token stored on the Client side?
Goal:
I would like to understand how the browser (client-side) stores this authorization token. I dont Need to get the data or know how to scrape with selenium or sthg. I would just be interested in the mechanics behind.
What i tried:
I find the token in the page source: view-source:https://helm.csod.com/ux/ats/careersite/4/home?c=helm&lang=de-DE.
It seems like there is an object csod created in /player-career-site/1.15.4/pages/home.js.
then the key is stored in csod.context.
Finally, csod.player.initialize(csod.context) is called.
Unfortunately, i failed digging in the Code and finding These function as there where too many Matches for initialize and my js are skills too bad.
As storage i am only Aware of the Cookies. It might be transformed / encrypted and stored in the cookies? But how is it then restored to the "original" token, before being added to the request Header?
This seems to be a CSRF prevent method.
The token is created with a key in the back end, it stores the original key in a session and sends the token to the client side.
When the client sends a request, the token is posted with the data as a header or with the data, then the back end gets the stored key in the session, generate the token with the same method and compare it with the posted token. If they are equal there is no problem, access granted.
It is not necessary to restore as you can't decrypt that depending on the algorithm (sha256, md5, etc)
And the browser don't do that, as it can be manipulated, there is no sense to.
The token sent here is JWT(JSON Web Token). This is a widely used standard authentication mechanism.
You can create your own token in any languages like JS, Java, PHP, Python, etc.
I am adding a basic authentication flow:
Let's say a user comes on a form. Enter his email & password.
Now an HTTP request is being sent to the server with credentials. The backend server checks the details and if successful, then returns a response containing the authentication token.
Most of the time this token is stored in localstorage and sometimes in cookies.
Now for every request the token is picked from the stored location and sent in the header.
On the backend, it is checked if the request header has the details or not. And then respond accordingly.
At last, whenever someone logs out then that token is removed from the front end.
I hope it helps! Let me know if you have any queries

Using firebase jwt to authenticate users to external server\service?

Okay so in my iOS app I log the user into firebase, then get the jwt token. So now I have my server with an api which accepts an idtoken in the header of the GET.
What do I do here? Certainly I wouldn't be validating the JWT againt firebase on every single API call right? I mean its fast, but that adds latency with a second external check, no? How does one simply just decode that guy in C#? I have an Auth0 layer already and that decodes the JWT with my server-stored secret, but that same code doesn't work for the Firebase token.
Could it just be decoded then extract the user details from that, maybe just check expiry and if expiry > X months it's still okay?
In order to verify Firebase ID tokens and JWTs in general, you only make a network call on your server to get the public certs which are usually not updated for several hours. You could cache that and try to verify with an ID token and if it fails, only then, load the new public certs.
And yes, you must verify the ID token on each call especially since Firebase ID tokens expire after typically an hour and need to be refreshed continuously.

OAuth access token and refresh token creation

I'm implementing my own OAuth authentication system (with refresh_token support) for an app and I have some questions about how to do it:
Client identification: The client is registered in the auth server and gets a client_id and a client_secret. How do I generate it? is there some kind of relation between both values?.
User authentication: The client sends the users_credentials (username+password for example) + client_id and gets a refresh_token and (temp?)access_token. That access_token is the one I should use in further request or I should use a accesss_token`=F(refresh_token,access_token,client_secret). In the second case what does the F function consist on?
Access token refresh: The client send client_id, refresh_token and gets a access_token (and a optional new refresh_token). Does the access_token need the same conversion (whatever it be), as in the point 2?
If I'm wrong, when and how is the client_secret used?
Complete answers and concrete examples will be "bountied".
The authorisation/authentication server generates these values when you create an account with them (for instance when you create a developer account with Facebook or Google). If you are doing these parts yourself, they should be cryptographically secure pseudo-random numbers or letters. Remember that the client ID is usually publically visible, so choose a reasonably large set of alpha-numerics (I use 30 characters). The secret is private and can be harder to guess so I chose 30 digits with letters, numbers and symbols. These are not related to each other, it is just that one is public and the other isn't.
The usual way this works is that there is a browser redirect to the auth server passing the client id in the URL (and redirect uri) and specifically NOT the user id and password. The whole point of OAuth2 is that the client system never sees the user name and password, only the auth server. After this redirect, the auth server verifies the client id, checks the username/password (for instance) and then returns to the redirect uri with a temporary code. This temporary code is passed back to the Auth server in order to obtain an access token. Since this call is made as a POST from the server, it also passes the client secret to verify that it really is the correct client system and not someone who stole the client id from somewhere else. At this point, the auth server will return an access token (and optional refresh token - you do not need to use them, I don't).
If the client system wants to log the user in without them having to type in their username and password all the time, it can use a refresh token, if available, to call back onto the Auth server and if the Auth server is happy that the refresh token is still valid and any other business rules are correct, it can give you back another access token directly without the user being involved.
I recommend reading the OAuth2 spec here: OAuth2 Spec RFC6749. It can take a while but if you delete the bits you don't need and reduce the amount of data, there are plenty of useful examples in it.
FIRSTLY, The client identifier can be any string that you want, but it should be unique for each client. It can even be the client's choice if you wish.
The client secret should be a cryptographically strong random string. Here is how you could generate one in C#:
RandomNumberGenerator cryptoRandomDataGenerator = new RNGCryptoServiceProvider();
byte[] buffer = new byte[length];
cryptoRandomDataGenerator.GetBytes(buffer);
string uniq = Convert.ToBase64String(buffer);
return uniq;
SECONDLY, The whole point of OAuth is to allow external apps to do things on your behalf without asking for your credentials. So, you need to implement an authentication server that does the logging in part for you. The user opens the app and gets an option to Log in using your website. You tend out access tokens and refresh tokens once the user has keyed in his credentials. The app can then simply use the tokens to perform actions on the user's behalf. I wrote an answer to How would an efficient OAuth2.0 server / provider work? that explains how access tokens can be constructed.
Remember, the need for refresh tokens and the lifetime of access tokens purely depends on how you intend to use them and what does your security framework look like.
LASTLY, The refresh token can also be an HMAC encoded string/a JSON object as I had explained in the answer to the linked question. You can have random refresh tokens and a large backend storage to keep it to verify the tokens in the incoming requests, or have HMAC encoded strings for added security/less storage requirements/latency to decrypt/encrypt tokens.
Also, do make sure that you go through all the flows and possibly the RFC too as mentioned by Lukos.

Resources