Firebase Authentification and Flask - firebase

I am trying Firebase to authenticate users for a website that was initially built on Flask (using the flask login workflow with a postgres DB). However, I am not sure that I have a correct understanding of what would be considered best practices when using Firebase.
I read through this article, which I think has led me down a suboptimal path when it comes to actually managing users.
My questions are:
Should all the Firebase authentication be handled in the javascript?
If so, should I use the request.headers on the backend to verify the identity of the user?
Any tutorials (aside from the Firenotes one, which I am working through) much appreciated.

Should all the Firebase authentication be handled in the javascript?
No, it doesn't have to be JavaScript. But in general, you'll find that most apps using one of the existing Firebase Authentication providers handle the sign-in of the user in their client-side code, with calls to the authentication server.
If so, should I use the request.headers on the backend to verify the identity of the user?
When calling REST APIs Firebase itself passes the ID token of the authenticated user in the Authorization header, so that's a valid approach indeed. On the server you can then verify that the ID token is valid, and decide what data this user has access to.

Related

GAE3 Python and validating firebase token server side (do we need to call Firebase everytime?)

This is my first GAE app so please let me know if my approach is wrong. I have knowledge of Flask and have used Flask-Login before for my authentication needs. With GAE, it seems they suggest to use Firebase. Mine is not a SPA but I wanted to use Firebase UI and let it handle all the user authentication part.
Looking at the examples here https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/appengine/standard_python3/building-an-app/building-an-app-3/static/script.js#L42 , i can verify the token server side using the Python Admin SDK. https://firebase.google.com/docs/auth/admin/verify-id-tokens#python or a more developed example https://firebase.google.com/docs/auth/admin/manage-cookies#python . I am able to do this but I am a bit confused about the flow later on.
In the same example, they suggest to store the token (or some part of claims) as secured cookie. This is similar to how Flask Login also stores the cookie and then we verify the cookie in every request - but since in the case the backend is local REDIS or any storage, the validation is not expensive. But when using Firebase, it seems we will have to call Firebase for every api call to validate the token.
Otherwise, it could that be that user has changed their password or reset something in their Google/Facebook provider and we wont know at our server till we validate things at the provider end. This also prevents us from developing locally offline (or we write some logic to specially handle local development).
Whats the best way to solve this?
You can use the Firebase Admin SDK to manage users or to manage authentication tokens, according to the official documentation – marian.vladoi

How to verify that my firebase application is the one calling my API?

I have a firebase web app calling my Python API.
the user who is using my app does not need to login to use it but I still need to make sure that this request coming from my application
How can I verify the identity of the app sending the request?
There is no way to enforce that calls can only come from your application. In a database that is directly accessible from the internet, that is simply not possible. Anyone who can use your web app, can take the configuration data from that app and use the Firebase API to make their own calls.
That's why it's important that you enforce all business rules that you have for your database in Firebase's server-side security rules too. You can use these to enforce data structure, and (when combined with Firebase Authentication) ensure that all data access is authorized.
You can use Firebase Authentication without requiring your users to enter credentials by using anonymous authentication. This essentially gives your user a unique ID, that you can then use to identify that user (and the data they create) in security rules.

How to properly implement user authentication and authorization (FirebaseAuth with NodeJS backend)

I'm creating an app using firebase authentication and I'm still new to authentication and authorization. What I have already done is implement firebase authentication in the front end, when a user signs up successfully it will request to the backendend and verify its idToken firebase admin. When it's verified, the user's data will then be stored in the database together with the uid returned in verifying the idToken.
All is working but I have no clear idea on the best practices on authentication, am I on the right track? From what I've read, authenticated client should also pass a token in the header.
Should I return the uid to the client and use it in the header? If so, should the backend use it to check if there's a matching token in the database every client request?
I'm really quite lost with the log in flow standards, any answers are much appreciated thank you.
All right, so the first thing to understand is that Firebase operates on a client-side paradigm, meaning that you actually don't need to and should carefully consider whether you need to conduct Firebase operations server side. In principle, you can do everything on javascript on the web browser. or Android app. or iOS app.
If you do decide to move some functions server side, next best solution is to do them as hosted cloud functions in firebase too. See:
Callable cloud functions
If for some reason you need to deploy and host your own code, then you can continue as you are, doing auth client side, passing the token, decoding the token with node admin, and manually checking the user permissions as applicable.

How to implement Firebase custom authentication backend?

I want custom firebase authentication where a user manages the roles of subordinate users. I need guidance on understanding on how to implement my own backend authentication system. Everywhere the documentation keeps mentioning that 'send the username and password to your backend that will generate a custom token'. What is this backend? where do I pursue this? My knowledge domain is firebase, firebase functions, angular 2/4, ionic2 for this discussion... thanks
To use custom authentication, you need to create a JSON Web Token (JWT) on your existing backend server, after you have used your existing backend server to validate the username and password of the user (or however else your backend server validates your users).
To create that JWT, use the configuration described at https://firebase.google.com/docs/auth/admin/create-custom-tokens?authuser=0#create_custom_tokens_using_a_third-party_jwt_library
There is PHP and Ruby code available at that page, for anyone using a language that does not have an SDK available from Google, but which does have a JWT library available.
The JWT is signed with your private key, which you can obtain as indicated at https://firebase.google.com/docs/auth/admin/create-custom-tokens?authuser=0#create_custom_tokens_using_a_third-party_jwt_library
Although that page describes initializing the SDK, this section also has instructions for creating the private key for your service account using the Firebase console at https://console.firebase.google.com/u/0/project/_/settings/serviceaccounts/adminsdk
You will have to send the email password to the firebase sdk in using javascript in web then when the sdk success functions tell that the user has been authenticated the web page will send result to your backend server (can be nodejs or php etc) from there you have to manage your own database to handle all the role base access.
Firebase is basically authenticating the user for you and telling you that you can identify this user using the following userid and then build your own system.
Firebase has access rules but those you have to define first you cannot fully customize them for each user.
For password auth see this:
https://firebase.google.com/docs/auth/web/password-auth
An easy way to do custom auth with Firebase is using an external identity provider. Auth0 is an example of such a provider.
Guide:
https://shusson.info/post/using-firebase-and-auth0-together
code:
https://github.com/shusson/firebase-custom-auth

Is it possible to use an external Identity Provider in a Web API with ASP.NET 5?

Reading this question, #Pinpoint's answer and the further discussion on comments, I'm well aware that natively we can't add an identity provider to our apps developed with ASP.NET 5. One possible replacement for the legacy OAuthAuthorizationServerMiddleware is then provided by the AspNet.Security.OpenIdConnect.Server as I've found in many places.
Now, there is one point that I'm still unsure about all this because I'm really not an expert in security, so my knowledge about OAuth is not very deep. My doubt is the following: is it possible to use an external identity provider when using OAuth to protect one RESTful API?
Notice that I'm not talking about adding social login to one website, I'm talking about using one external identity provider in one RESTful API.
My point is, this makes me a little confused yet, because I always thought this should be a concern of my app.
So my question here is: when using OAuth and ASP.NET 5, is it possible to use an external identity provider, other than implementing one? If it is possible, how this works in short? I mean, my app still needs to be able to manage the identities of users, in the sense that it needs to manage claims and so on.
In that case, if it is really possible, how the flow would be? The external identity provider should issue the tokens? But how my app would be able to verify those tokens and manage users identities?
EDIT: One of the reasons I feel unsure about that is that when we use the UseOAuthAuthentication extension method, we set up one callback path which is described as
The request path within the application's base path where the user-agent will be returned. The middleware will process this request when it arrives.
Now, if we are developing a site, then this really does make sense. The person goes there, click a button to login with a provider like Facebook. The user is redirected to Facebook's page and then after he logs in, he is redirected to some page of the site.
On the other hand, with a RESTful API this is meaningless. There is no notion of being redirected.
This makes it seems that the usage of external providers is only for sites and not for RESTful API's. This is the main point of my question.
My doubt is the following: is it possible to use an external identity provider when using OAuth to protect one RESTful API?
Yes, it's definitely possible. This is exactly what you do when you use Azure Active Directory to protect your API endpoints:
app.UseOAuthBearerAuthentication(options => {
options.AutomaticAuthenticate = true;
options.Authority = "https://login.windows.net/tushartest.onmicrosoft.com";
options.Audience = "https://TusharTest.onmicrosoft.com/TodoListService-ManualJwt";
});
The next legitimate question is: if you can use the tokens issued by AAD to protect your API, why couldn't you do the same thing with Facebook or Google tokens?
Unlike Facebook or Google, AAD issues completely standardized tokens named JWT tokens that the OAuth2 bearer middleware can "read" and "verify" to determine whether the token is still valid and was really issued for your API (i.e if the audience attached with the token corresponds to your API. You can control this value using the resource parameter when making your authorization request).
You can't do something similar with FB or Google tokens, since they are totally opaque. Actually, it's not really surprising since these tokens have only one objective: allowing you to query FB or Google APIs, not your own ones (these social providers don't allow to set the audience of the access token).
Since you can't read the token yourself, the only option is to ask FB or Google whether it is still valid to make sure your API doesn't accept invalid tokens. That's something you can (easily) do with Facebook as they offer a "token inspection endpoint" you can query for that: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow (see the Inspecting access tokens chapter). This way, you can ensure the token is not expired and determine the user corresponding to the token.
Sadly, this approach has two downsides:
You have to make an extra HTTP call to the Facebook endpoint to validate the access token, which implies caching received tokens to avoid flooding Facebook with too many requests.
As the access token is not issued for your own API, you MUST absolutely ensure that the access token was issued to a client application you fully trust, or it will allow any third party developer to use his own FB/Google tokens with your API without having to request user's consent. This is - obviously - a major security concern.
You can find more information in the last part of this SO answer (it's for Katana and about Dropbox, but you should get the idea): OWIN/OAuth2 3rd party login: Authentication from Client App, Authorization from Web API
So my question here is: when using OAuth and ASP.NET 5, is it possible to use an external identity provider, other than implementing one? If it is possible, how this works in short? I mean, my app still needs to be able to manage the identities of users, in the sense that it needs to manage claims and so on.
In that case, if it is really possible, how the flow would be? The external identity provider should issue the tokens? But how my app would be able to verify those tokens and manage users identities?
To work around the limitations mentioned in the previous part, the best option is - as you've already figured out - to create your own authorization/authentication server. This way, your API doesn't (directly) accept FB or Google tokens but the tokens issued by your own server, that can possibly redirect your users to FB or Google for authentication.
This is exactly what this sample does: https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/vNext/samples/Mvc
The user is invited by the client application (Mvc.Client) to authenticate with your authorization server (Mvc.Server) so he can get an access token to later query the API (also in Mvc.Server). For that, the user is redirected to your authorization server, which itself offers you to authenticate with Google or Twitter.
When this external authentication step is done, the user is redirected back to your authorization server (Mvc.Server), where he's asked to give his consent for the client app (Mvc.Client) to access his personal data.
When the consent is given, the user is redirected back to the client application with the access token you can use to query the API endpoint.

Resources