Firebase Custom Claims security rules database - firebase-realtime-database

Hi i would like to ask if in firebase it is possible to add custom Claims like that:
{
roles:["ROLE_A","ROLE_B"]
}
And at the same time write correct realtime databse security rules like :
".read": "auth.token.roles.contains('ROLE_A')
This is my databse example:
"root":{
"users":{
"nodeA":{
}
"nodeB":{
}
}
}
When i try to wryte the rule i have
the same thing works with someting like that

That should work. Just have in mind that the custom claims have a limit in size of 1000 bytes. If you need to save to many roles that could break your app authorization logic.
I like to use the custom claims for very basic roles like isAdmin and the rest over the datbase. You can change the custom claims only form a secured backend and in Firebase that is probably a cloud function. You would need to save those roles in a database for your forntend to see what roles a user has or not and sync those with the users custom claims. That data needs to be secured for users authorized to change them. When you already have that you can also use the same data from the database to write your database rules. It's also very easy to sync them between both databases.

Related

Firebase Realtime Rules: Split users into multiple groups w/ role-based (token) authentication

Each user is authenticated w/ a token of state and city.
I want the users to be able to read data at /data/$state, /data/$state/$city
For /data/$state/$city I can add a rule (on /data/$state/$city):
.read: $state == auth.token.state && $city == auth.token.city",
This would work well, how ever to grant access to /data/$state access I would write (on /data/$state):
.read: $state == auth.token.state",
Which would grant read access down the line to any node in any city (in the state, /data/$state/*) and ignore the previous one (based on Firebase Realtime rules where top rules takes precedence).
Do I have any way to handle this beside flattening my data into:
/Cities/$state/$city
/States/$state
Thus handling security for each case in their respective node?
Thanks!
No, as explained in the doc, it is not possible:
.read and .write rules work from top-down, with shallower rules
overriding deeper rules.
...
Shallower security rules override rules at deeper paths. Child rules
can only grant additional privileges to what parent nodes have already
declared. They cannot revoke a read or write privilege.
So you indeed need to denormalize your data as mentioned at the end of your question. Note that the update() method allows to easily write to different nodes, see the example in the doc.

How can I use group membership to restrict results?

In an MVC application, for a given action that all users are authorized to perform, I would like to filter results based on the user's group membership. For instance ...
Users in GroupA should only see records pertaining to BuildingX.
Users in GroupB should only see records pertaining to BuildingY.
Users in GroupC should see all records.
I have no problem using authorization filters to restrict access to Actions, but I'm having a much harder time finding how to restrict access to data short of explicitly modifying statements every place where data is fetched.
Assuming your records are in a database, the roles membership model doesn't extend to the database out of the box. You can build a roles-based access control for your database, but you will likely save time using a simpler approach. For example, using code like this in your controller:
if (Roles.IsUserInRole("GroupA")) {
// Get data for GroupA.
}
// Display data...
A year later, working on a different but related issue, I found the EntityFramework.DynamicFilters package which does exactly what I need!

grails field level security - spring acl

I am working on a project where we have requirement to provide field level access to users.
Example:
Suppose there is an entity named employee with several fields
The application should allow secure access at the field level of the entity.
According to the access user is allowed to edit / read the fields.
We have thought of an implementation using spring acl but it provides instance level security.
Could someone please let know an elegant way to implement it?
Thanks in advance.
Take a look at the fields plugin.
It allows you to control how individual fields are rendered.
You could implement a security check within each field's _field.gsp fragment, or you could override the plugin's taglib's f:all method and add a security check there if you prefer.
You could use the plugin for that, but you'd need to do some extra work. The ACL support in Spring Security basically lets you say "grant permission x on object instance y (of type "foo") with id z to person p". There is an example permissions class with standard instances like Read, Write, Admin, etc., but the underlying infrastructure only works with the numbers 1, 2, 4, 8, etc. so you can easily define your own permission types - they're really just mappings of human-readable names to numbers. You typically grant permissions on domain object instances, but under the hood the names of the domain classes are just strings, so you could store any type name there. And the ids can be any value, e.g. a number or a string.
You wouldn't be able to use the #PreAuthorize and #PostFilter annotations on service methods, but you can still query the ACL beans to see if, given a field or whatever you want, the currently authenticated user is allowed to perform some action.

Method security in Spring Security

I have a question regarding using Spring Security to protect against SQL injection. First of all, I know that use prepared statement can protect from any SQL injection. But In my project I want to show that use Spring Security could help to protect or mitigate against this kind of attack. what i did so far, i made connection using JDBC & Spring and I applied Spring Security and every thing is fine. My question is in my project i used two ways to protect against SQL injection. The first one is Santizing user input and the second one is using Spring Security. I could pass malicious input through Sanitizaing and I want to show that the role of spring security. for example, I pass this input:
TV' UNION SELECT credit_no From credit;--
In this case how I can tell Spring security that it doesnot give any users the credit number. By the way, I used method security level. Just I want to give me an easy way to analyze the user input to see If it has access to data which he asked such as credit.
I hope that clear
Well, your question is not 100% clear, and it may vary on your architecture, but pre post annotations can work well to grab user input.
You can create your own permission evaluator and check permission for pre authorization in your methods.
#PostFilter("hasPermission(filterObject, 'customoperation')")
public CreditCard getCreditCard(String userInput) {
//
}
and your hasPermission method (that you've read about in the link above) goes something like:
public boolean hasPermission(Authentication authentication,
Object target, Object permission) {
if ("customoperation".equals(permission)) {
//your logic here, returning true or false, filtering the object
}
return false;
}
You can also extend the expression handler to use custom functions. Check this answer.

Persisting/caching data between requests - common approach

I'm developing an Asp.net (MVC but this doesn't really matter) application. I have a custom IHttpModule that's responsible for the PostAuthenticateRequest to change user principal & identity.
I'm storing UserID and UserName in authentication cookie when user logs-in. I have an IUser (implemented by DAO and Business Objects layer, each with their own additional members) that I need all over Business Service classes. When a user wants anything I have to provide IUser object instance (usually from Business Objects layer) so providing ID from the auth ticket isn't sufficient.
So I'm thinking of how and where would be best to persist logged in user's IUser data?
I don't want to fetch it every time from the DB (based on authentication ticket's UserID data)
I can't store it in Session since I have to work inside PostAuthenticateRequest, where Session isn't ready yet
I want all the functionality to be encapsulated within my custom IHttpModule
Choices that I see:
Cache
Cookie
(Session) - by moving from PostAuthenticateRequest to PostAcquireRequestState event and change principal/identity there, but I'd like to avoid this
Processes that seem to complicate things are:
User logs-in, user data is fetched from the DB and persisted somehow for later requests
User logs-out, user data has to be removed from persisted medium automagically
User changes own profile, user data has to be discarded and reread on next request from the DB
I wan't all these to be handled automatically by HttpModule (if possible) to eliminate developer's errors of forgetting to reset these things.
What I also don't want is to write/read some hardcoded variables/keys and manipulate them in other parts of the application. This would only present technical debt.
Questions
What would you suggest?
How does SO persist user data between requests?
Given your requirements, I suppose the best solution is to retrieve the ID from the cookie and use it to index into the Http Cache (HttpContext.Current.Cache).
If you want to maintain how users access it, wrap the Cache in a "UserCache" object. The object could be constructed by an HttpModule and stored as a (wait for it...) singleton within the cache itself or, better yet, just constructed when needed to pull from the http cache. This would depend on where you need to access it and whether HttpContext.Current.Cache is directly available. The lazy implementation is below.
Again, this is for clarity and is not how I'd actually implement it.
public class UserCache
{
public IUser GetUser(object userKey)
{
return HttpContext.Current.Cache[userKey];
}
public void AddUser(object userKey, IUser user)
{
/* this could pull the key from the user object as well. */
HttpContext.Current.Cache.Add(/* add the object with key and a sliding expiration that is slightly greater than session timeout */);
}
public void ExpireUser(object userKey)
{
HttpContext.Current.Cache.Remove(userKey);
}
/* If you don't want to do SQL cache dependency */
public void UpdateUser(object userKey, IUser user)
{
HttpContext.Current.Cache.Insert(/* ... */);
}
}
Using the default caching mechanisms (or better yet a caching mechanism supplied by DI so you're not tied to an implementation), you can set an expiration to automatically remove users from the cache as mentioned in the comment. You can setup the cache to be dependent on SQL server updates as well to handle the updates or manually update it as part of the service to save changes.
More information about the default cache is available here. More information about cache dependencies is available here.
In the HttpModule itself, I suppose you could do some magic in the EndRequest event to see if the request is authenticated and then log the user out based on the cookie, but I'm not sure if that would work as I've never tried it. You might want to have a look at this article on MSDN from WAY back in the 1.1 days and see if it answers some of the problems you are trying to solve.
As for the SO architecture and how they do it, I'd imagine they load it when needed because they keep most of the database in RAM at all times (http://highscalability.com/stack-overflow-architecture).

Resources