Iam working on a flutter mobile application where i use Google SignIn for Auth, is there a way to authorize users with existing account only?
Prevent users from creating new accounts? I've looked for the same thing without finding a way to do this with any Firebase project setting.
The solution, I believe, is consider the difference between authentication and authorization. Firebase's Authentication service is aptly named. It does authentication
- validates that a user is actually who they claim to be. It does not do authorization - control what actions authenticated users are allowed to perform or what data they can access within an application. App developers have to be responsible for managing user authorization.
One way to do this is to maintain a collection of "authorized users" in Firestore, for example. When a user authenticates, your app would perform a lookup to see if the current user is actually authorized or not. Security rules can be written for Firestore and Firebase Cloud Storage to also validate that the current user is in the "authorized users" collection before allowing access to data. But this requires extra data queries to obtain this authorization info.
The authorization method I prefer is to use Custom Claims which can be assigned using the Firebase Admin library. A custom claim can be added to an existing user account that can act as a flag indicating what type of authorization they're granted. Front-end code can check the authentication token they've been issued for the custom claim to determine the authorization they've been granted. Server-side code and security rules can also check for those required custom claims within submitted requests.
Realistically, any application you build where different users might have different levels of access will require you to deal with authorization. I believe that assigning carefully thought-out custom claims is the best solution.
Related
I've become very frustrated with the landscape of API creation and authentication/authorization. I would like to find a solution that doesn't require lots of additional complexity (creating new services myself, standing up and maintaining an instance of Keycloak, and so forth) – ideally a managed service (like Auth0 ... but Auth0 doesn't meet my requirements) – that centralizes the management of users and permissions, and allows me to add attributes to users.
Some context:
Suppose you have an API that has a variety of routes:
GET /customers
GET/POST/DELETE /customers/{id}
GET /customers/{id}/orders
GET/POST/DELETE /customers/{id}/orders
You can imagine that you have a case where you have users that have read-only access, and others that can read, create and delete customers and orders. You can also imagine that you may have the need to programmatically access the API, via a service account or access token (such as with Github PATs).
This could be set up with FastAPI or some other framework, such that when a route is accessed it checks that the user, or the access token – or in essence the credentials being used to access the API – has the necessary permissions.
What would be ideal, then, is to have a system that allows me to create users, and from that system the users can – provided they have the permissions in the identity management system to do so – create machine credentials (again, like with Github PATs, but perhaps something that can generate a JWT for consistency of credentials). Users can be added to groups that provide them with roles, and therefore permissions, or they can be assigned roles directly. Ultimately, it's a system that:
Allows user creation and management
Allows users to be grouped, groups can have roles that cascade to users
Allows users to be assigned to roles directly
Allow users to create credentials for programmatic access
Does not make management of users, roles, and so forth, onerous
Allows services (such as a REST API) using these identities for authentication to get the permissions and other information associated with credentials. In the case of other information, this could be included as claims in a JWT – this would require a system that allows claims to be added programmatically to the ID token/JWT.
In my experience, the closest thing to this is Keycloak. Unfortunately, it is a decent amount of work to maintain a Keycloak instance. Still, Keycloak does not provide number 4 in the list above. Does anyone else have experience addressing this issue? I would like to avoid have to manage users and permissions myself, because I have limited resources and that isn't my area of expertise.
Similar solutions:
Keycloak – hits most of the points, except for allowing users to create machine credentials. I'd like to avoid having to set up and maintain a Keycloak instance. Not sure if I can add attributes (claims or something else) to a machine/service account JWT.
Auth0 – Hits some of these, but doesn't allow me to add attributes to machine/service account JWTs, although it will add permissions to them (but that isn't enough).
Here is how my application should work:
Users can use some functionalities of my application if they have enough chips (token) which they can buy from another application, or they can be granted to them upon some event, whatever.
Users have an attribute associated with them called 'chip', which represents some number. This information should be represented as a claim, probably.
I want Keycloak to do this authorization for me - to check whether user can use the functionality or not. I've come across JavaScript-based policies. It's seems they are able to operate on informations in tokens - like user email etc, but this is not my case where token can contain obsolete information, i.e. when token was generated user had enough chips but since then he spent them.
Maybe token should be refreshed upon spending chips, but in that case, would it be updated with current informations bound to user? Or maybe authorization service can somehow access database during evaluation of a policy? Could this work or are there any elegant solutions to this use case?
Keycloak is not here to check if the user has enough money. Keycloak is here to say if the user is authenticated and if he has the roles for a certain application (admin, user...).
Checking if the user has enough money should be on server-side. For an incoming request, you have to check in the database if the user has enough chips to access the application and if he hasn't you return 403.
I am working to build an application which would be able to create custom audiences for many of our clients for facebook ads. I came to know that the most suitable access token for this purpose is system user token (correct me if I am wrong). To get regular user access tokens, we can make a user go through the traditional oAuth flow, I am looking for something similar to get system user access token. How can I get it for any of my clients? Thanks
You must create your system users in the Business Manager of your company:
https://business.facebook.com/settings/system-users?business_id=<YOUR_BUSINESS_ID>
Once you create a system user, you can generate a token for him associated with a given app.
Meanwhile, on your business settings (as stated in the docs) you can request access to an ad_account.
Request Access to an Ad Account: If you request access to an ad
account in Business Manager, the admin of that Business Manager can
grant you permission to work on it.
Once your client gives your Business permission to work with one or more of their ad_accounts, those ad_accounts will appear in your Business Manager. (menu on the left).
At that point, when checking the profile of your system users, you can click on assign assets to give the system user access to pages and ad_accounts.
The token you generated for the pair [system_user,app_id] does not need to be reissued to reflect the addition of assets to which the system_user has access.
I apologize if this has been answered, but I have been searching for hours, and still don't quite understand. This is a specific question, and not a "which is best" question.
Specific questions are in italic.
I have created a RESTful API, which was at first meant to be completely open. However, the organization has now decided to create a first-party mobile app to consume and (to some degree) update the data.
I am investigating authentication frameworks (oAuth2), and was not sure if oAuth2 was the correct way to go to meet our goals. And, if it is, which Authorization Grants applied to which set of users.
Our goals are:
To allow users to login and create accounts in the first-party app, entirely through oAuth 2 providers (twitter, facebook, google). These users would have access to the greatest set of data via the first-party app.
Assign different roles to the users (admin, moderator, etc).
Allow other applications to register, receive token credentials, and have limited write access or expanded access to the data. This would open them for creating third-party apps or research systems.
Finally, we would like to keep some of the data completely open, with no authentication needed.
So, am I right in assuming that we want to setup an oAuth2 *Server* (Authorization and Resource Server)?
If so, which Authorization Grants apply to the above situations?
One last question: For users using the first party app, would the app be responsible for logging them in and keeping their access credentials? The API server serves NO html, and is 100% RESTful. Does it need to serve login forms?
If you need to both authenticate and authorize users to your API based on various OAuth2 social logins, you do need some kind of API server or service where you can define your users and groups/role and the scopes that are available to users based on your rules.
Some cloud-hosted options for this are:
Auth0
Firebase
If you integrate with a service such as the ones above, you can let the service take care of authenticating users and just make sure that every user call checks against the service first for permission before it goes ahead and does anything.
I am building a messaging application using BackboneJS which naturally persists using a REST interface.
The issue I'm having is that I don't know how to restrict what data a user can pull back from the API. For instance a call to /messages would, at the moment, return messages for ALL users. I would like that resource to only return messages belonging to the current user.
Searching online seems to indicate that oAuth2 is the best way to solve this issue but all the tutorials talk about been redirected to another place to confirm access and retrieve an access token.
Given that my users will have already logged into the message application and that the REST API is actually part of the same application I don't like the idea of asking the users to confirm that my own app can access my own API.
Is there a better way?
oAuth2 is probably your best bet -- you definitely don't want to roll your own security. However, the flavor of oAuth2 you are thinking of is probably not what you want.
oAuth2 has four different flavors, known as authorization grant types:
Authorization code: This is the type you are thinking about. It is often called three-legged oAuth, because there are three actors in the token granting process (app, resource owner, and user). The app asks the user whether it is ok for the resource owner to give specific type(s) of access to the resource. It is a rather complex process that allows the validation of user credentials without allowing the app access to them. This is not necessary in your case, since you are both the app and resource owner.
Client credentials: This is a method for authorizing a client application with the server. It does not use user credentials at all. If you completely trust your client application (all client applications) to correctly protect user data and not expose other user's data to the user using the app, or you are providing only non-user data via the API (for example, map data or catalog data), you might be able to use this fairly simple type of oAuth2. However, if you want to be vigilant in protecting user data (and not allow apps to get to the data without the user providing credentials), you might not use this one.
Resource owner password credentials: The username and password of the user is passed via https to your backend server, which authenticates and authorizes access by providing an access token. The access token can then be passed with each call, and it remains valid for accessing the backend until a configurable time period has elapsed. This means that someone intercepting the token could only use it successfully for a limited amount of time (some number of minutes, generally). The interceptor would not know the username and password of the user. In addition, you can supply the app with a refresh token, which can be used to get a new access token once it has expired (until the refresh token expires -- usually with a significantly longer expiration date). Since the credentials are not passed across the wire often (and must only be passed encrypted), this is often the best solution for protecting user credentials and not requiring the user to pass them in often (good user experience). Implementation is much simpler than for the authorization code grant type.
Implicit: This is the least secure method -- no credentials are validated server side at all. This is usually used for client side scripting languages where credentials cannot be stored safely. If you are worried about security at all, avoid this type if possible.
So, check out OAuth 2.0, and look for the resource owner password credentials grant type.