How should my own server verify a web client signed in with firebase? [duplicate] - firebase-authentication

This question already has answers here:
Firebase: How to generate access token from username and password on the server?
(2 answers)
Firebase authentication for private server
(1 answer)
Closed last year.
Web client signs in successfully directly with firebase.
Now it wants to talk to my own nodejs (non-firebase) server.
How does my server verify the web-client is really signed in with firebase? Note: my server doesn't manage any user account passwords.
https://firebase.google.com/docs/auth/admin/custom-claims
Seems to use this flow:
For simplicity, let me call my good web client Bob.
Step 1: Bob needs to send password + email to my own (non-firebase) server. Now my server knows Bob is Bob, and gives Bob client-side a token "bob-token"
Step 2: Bob on client-side calls firebase firebaseTokenFromFirebase = firebaseFunction.signInWithToken("bob-token")
Step 3: Bob sends firebaseToken to my own server
Step 4: On my own server, I can make a verification request directly to firebase bobReallySignedIntoFirebase = firebaseAdmin.verify(firebaseTokenFromFirebase). And if ok, now my server knows Bob really signed into Firebase.
But question: My server doesn't manage passwords at all. So my server cannot verify "Bob is Bob" in Step 1. Is there a way for my server to only rely on Firebase?
Ideally, Bob signs in directly with firebase, and receives an asymmetrically signed JWT (containing Bob's basic info) that can be independently verified by my own server (my server only needs the public key; firebase produces the JWT with the private key).

There is no way to sign a specific user in to Firebase from the Admin SDKs, as the Admin SDK doesn't have the concept of a current user.
The idiomatic approach is to sign in your users in their client-side code with a Firebase SDK, and then pass the ID token to your server when you need to establish identity/authority. This is what most Firebase SDKs and services also do under the hood.
If you want to sign your users in on your server, you'll have to call the Firebase Authentication REST API.
Also see:
Firebase: How to generate access token from username and password on the server?
Firebase authentication for private server

Related

Storing client secret on client side

I'm using an external service called auth0 in order to get an access token and let my users use my api. Auth0 is using Oauth2 protocol.
In short The user adds a username and a password, I'm doing a call to auth0 by using a client_id (apps have an id) and client_secret and I get an jwt access token in return. Then from there I carry this access token to have access to my own api since I can check its validity.
I have been looking around about how secure it is to store client_id and client_secret on the client side (e.g. web (javascript)/mobile (native or hybrid with ionic)) and everybody was saying that it's not secure since everybody can reverse engineer the code and get the client_id and client_secret. Ok...I can take it...what Can I do with them if I don't have credentials in order to get the access token?
Given that I don't want to store the client_id and the client_secret, one solutions I have thought is to make a direct call to my api (Java) with the credentials and then my api make a call to auth0 and return the corresponding access token. In this way the client_id and client_secret is stored in the backend and somebody cannot get them easily. Is that safe?
However I have some endpoints, e.g. creating use account, sending sms for phone validation etc, that cannot have credentials. How do I protect the api in such case? If I can't store my own access token on the client side how could I get an access token and access my own api without credentials?
Thanks
One possible solution that OAuth spec suggests is that you could have three different servers for your application.
client-side
backend server and an additional authentication server.
The preferred way of doing this would be that the client would send the user credentials to the authentication server. The authentication server would be a back-end server which contains the client secret
The authentication server will authenticate the credentials and return back the token.
The client will then use the token obtained from the authentication server to access the resource API server.
If you wanna know more check out this video
https://www.youtube.com/watch?v=rCkDE2me_qk
In my opinion you are almost certainly using the wrong OAuth flow. I use Auth0 with Ionic as both a web app and a native Cordova app. I don't have the client secret in my client code at all.
If you follow the Auth0 quickstarts (https://auth0.com/docs/quickstarts), you should be choosing (Native/Mobile App) if you are deploying to app stores, and (Single-Page App) if you are deploying the web version of Ionic. From there you can pick Cordova (for native) or Angular (for SPA). These should give you instructions that implement OAuth flows which DO NOT require your client secret. My guess would be you are referencing a "Regular Web App" quickstart, which runs server-side and CAN safely hold the client secret. That's not the world you're coding in if you are using Ionic Hybrid/Native.
I would consider wrapping the call to Auth0 into your own server side implementation as safe. Your API takes user credentials and then calls Auth0 and this way your client_id/secret are secure on your server and the client can be reverse-engineered all the way without compromising your security.
Regarding the other APIs which cannot have credentials you are pretty much out of luck. Their very use case is to be used by an unauthenticated third party, so at least the account creation API cannot really be protected. However you can still use some nicely designed constraints to limit the attack surface. E.g. you can require an email address/phone number to register and you will not allow the same address/phone number twice. If you set up your process that you first need to confirm your email address before you can validate your phone number this will make the life of an attacker a lot harder. He would need a real working email address, and some automation to receive your confirmation mails before he could get to call your SMS service. You could also rate-limit the service per IP-address so an attacker cannot cause your SMS cost to skyrocket by issuing a lot of calls for SMS validation in a short period of time.

Angular 5/6 log-in authentication

recently I am working with an upgrade from legacy project to new one by using Angular 5 project with asp.net core web api.
While for the logging authentication process, usually we should NOT send original password to database but encrypt it, currently I am not sure which way below would be the best approach?
Encrypted password through Angular/Typescript then send to web api
Encrypted password through Angular/Typescript then send to web api then encrypt it again, finally send to database for verification.
Send original password to web api then inside encrypt it then send to database for verification.
Or any suggestion that's different from above?
The secure way is to use Identity Provider such as Azure AD or IdentityServer. The recommend approach is OAuth 2 Implicit Flow for SPAs.
If you cannot use Identity Provider, then option 3 could be used with few modifications -
Angular app posts username and password to server over HTTPS, and the server validates with hashed password stored in database.
If the user is valid, then response JSON Web Token (JWT) back to Angular app.

What is best suited to interface with authentication servers for a CLI tool?

I am developing two linux programs, a CLI client and a server communicating via gRPC, and I now would like to authenticate users against a given private authorization server such as LDAP, Active Directory, etc.
I am confused regarding the various possible authentication flows. I think I can't use any classical flow including HTTP redirects since I shouldn't rely on a browser being installed or having internet access. I can't even define an endpoint I could redirect to (servers don't have internet access, and both are behind NATs).
So I was thinking of trying to store user's credentials as a JWT token file in the user's computer and then load it from my CLI client program to include it in my RPC requests and then validate it on the server-side. But, supposing I'm right, then what would be the best standard way of getting this token file?
If you had a browser you could use OAuth and the 'oob' (out of band) method where the CLI opens the browser and after the user authenticates it displays a number which the user copy/pastes into the CLI. This how my flickr backup CLI works. The number they copy/paste is because the CLI has no OAuth endpoint and the number is their access token to allow me to call the flickr api on their behalf.
If you can't use a browser the CLI can just accept a username/password from the user, send it to the server and receive a token in return. You don't really need anything fancy like JWT. A simple UUID would be enough. The UUID 'asserts' that the user is allowed to access the server's other RPC methods. The server would validate the UUID token to make sure it's still valid. If you need user information from the token, the server could do that. Keeps the user information off the client's disk and only the CLI can access that information, if the token is still valid.
So in effect, you need a new server RPC method, perhaps, authenticate, that accepts a username and password and returns a UUID token. All other RPC methods then need to accept that token and validate it before performing the requested function. As part of the server-side authentication process, the server could associate that token with the user information it got from the LDAP server so you don't need to store that information on the client. Lets you encrypt it on the server too and if the client needs it, it asks for it using the UUID token if it's still valid (time to live?). If it's no longer valid, the client just needs to ask for username/password again and the server can re-authenticate the user via LDAP and refresh the token and user information.
gRPC has authentication protocols but the SSL/TLS doesn't seem to match your needs and the OAuth won't work as you don't have a browser. So perhaps rolling your own simple token service (authenticate) combined with LDAP authentication might be a workable option.

Is it mandatory to validate in my server the ID token with Google Sign in?

I implemented a simple web page where Google Sign In let users enter their Gmail and password in order to authenticate; then I made a simple server with Flask using Google Python API.
Everything is working fine, but I realized that I made the server before asking myself if I really need it: if I got it right, when user's credentials are verified after clicking on Google Sign In, the user is authenticated.
Client-side speaking, after a successful login a GoogleUser object is returned and it contains informations about the user; however, the user has already told me who he is since he provided me username and password.
So, why bother validating on a server an ID token if it is given after a successful login?
Some concepts sound contradictory to me: Google Sign-In for Websites: Authentication with backends video says that:
You can obtain an ID token upon the successful authentication
this would mean that the user is who he claims to be, but then, speaking about a server:
Note that the client libraries verify most of the information, but you still have to check if aud and iss claims are correct [on the server]
I thought that these two claims were verified on the client.
Is the GoogleUser object returned from a successful login enough to say "he is really that user"?
The ID token I send and verify in my server is necessary because there is no Google Sign-in button on the servers and is meant only for client side code?
So, why bother validating on a server an ID token if it is given after
a successful login?
The OAuth 2.0 ID Token provides the "verified" identity of the client. Since it is very easy to create an ID Token, you need to verify that the ID Token was created by a trusted Identity Provider. You verify the ID Token to prevent forgery attacks. How? By using the public key from the Identity Provider to verify the signature attached to the ID Token.
Note that the client libraries verify most of the information, but you
still have to check if aud and iss claims are correct [on the server]
I thought that these two claims were verified on the client.
In terms of security, you cannot trust anything from the client. You must verify everything. Hackers today think nothing of running scripts attacking any resource attached to a public IP address.
Is the GoogleUser object returned from a successful login enough to
say "he is really that user"?
No. The JavaScript code running at the browser can be modified. This means all data coming from the browser to your server should be consider "untrusted".
The ID token I send and verify in my server is necessary because there
is no Google Sign-in button on the servers and is meant only for
client side code?
You can implement 3-legged OAuth 2.0 which puts your server into the Authorization process. This way your server receives the Access Token, Refresh Token and ID Token. You then control what you provide to the client.

What is OAuth and how does it secure REST API calls? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have mobile application REST API calls which hits to my server without any token or security mechanisam.
I want to secure my API calls. I am trying to understand what is OAuth and how it will secure my mobile app REST API calls which are hitting to my server?
Also I want to know in details about the below fields which are used in OAuth . From where I will get below fields.
Consumer Key
Consumer Secret
Token
Token Secret
Timestamp
Nonce
Since most of providers use OAuth 2.0 and OAuth 1.0 has been deprecated by major providers, I will explain OAuth2.0
What is OAuth?
OAuth is an open standard for authorization, commonly used as a way for Internet users to log in to third party websites using their Microsoft, Google, Facebook, Twitter, One Network etc. accounts without exposing their password.
you can implement your own OAuth server, here I am explaining about social auth. so the term OAuth here after refers to social auth with OAuth.
In layman's terms, OAuth lets users login to your web service with accounts(Facebook, Google etc).
Terminology:
client: The user of your API.
Resource Owner (api server): Your API
Authorization Server (auth server): Facebook/Google etc auth server.
Authorization grant: the method by which you authorize a user. we are using Authorization code here.
Authorization code: A code that the auth server returns to the client which can be exchanged for an access token at the api server.
Access Token: A string that identifies a user, usually comes with an expiry period.
Consumer Key or APP_ID: a public key used by auth server to identify your application.
Consumer Secret or APP_SECRET: a private key which should be kept confidential.
The below terms have nothing to do with OAuth but are used with OAuth to make it more secure.
Timestamp: a string that tells date and time.
Nonce: a number or string which can be used only once.
source: http://smerity.com/
I will explain the diagram with Facebook login as an example.
Background;
consider you have done the below, before explaining the diagram:
You register an app with Facebook developers portal.
Facebook provides you two codes, 1) a secret_key and 2) an app_id
You designed a button which says Login with Facebook.
Now the diagram:
Client requests the API server.
API server redirects to login page saying. To access the data: please login with facebook to access the page
User clicks on the login with Facbook button, a new popup OAuth dialog opens. asking for facebook username and password.
User enters his username and password, then allow access to your app. auth server redirects the user to your website with a code as parameter in URL.
API Server is called on the step 4, API server captures code from URL.
API server call auth server with the provided client_secret
Auth server returns to the access token for the user to the API Server.
API server asks auth server for user information for the given access token.
Auth Server returns details about user, profile pic, email etc.
API server identifies the user, sends him the response along with access token.
client sends the access token to the api server on next request.
API server checks if access token is valid and respond.
When access token is expired, client is asked to login again.
Now, How does this secure your api?
Make the portions which need security as login required to access them. if the client who makes the request is not logged in to your api, send him to step 2 of the diagram.
So what is nonce? timestamp?
If someone steal an access token, he can get access to API server as long as the access token expires. So when the user requests a page, server sends him back a nonce which is stored in the server. the client signs the request with the recieved nonce and complete the request. as the nonce is only used once, server deletes the nonce. when an attacker grabs the nonce, and make a fake request to the server,server rejects the request as the one time number is invalid as its used already.
TimeStamp is used identify the time the token or nonce is created which is used to expire the token or nonce in a limited time frame (1-2seconds), the time needed for a request to complete.