grails field level security - spring acl - grails

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.

Related

Validity of domain entity method based on context or caller

I am currently reading about DDD and have a issue how to implement a certain validation.
Scenario:
I have an entity Group that contains a list of Members which in turn consists of a User and a MemberState (Member, Admin). The entity has a method MakeAdmin(User user) that turns a member into an admin.
The rule is: Only if the current user is admin of the group, it is allowed to turn the member to an admin.
I have three possible implementations in mind, with some caveats each.
Variant 1
Group enitity gets a dependency IUserContext injected via constructor to get the current user. With that the entity can check if the current user is admin and is allowed to switch the member state.
Caveat: I don't like that the domain entity has such a dependency injected and I don't think that is correct in a DDD view.
Variant 2
Method MakeAdmin() gets an additional parameter which turns it into MakeAdmin(User user, User currentUser). That removes the requirement for the IUserContext dependency in the entity.
Caveat: I am not sure if it is correct at all that the entity validates this rule, because it is not really an invariant of the entity.
Variant 3
Validate this rule in an application service, and only call MakeAdmin(User user) if validation passed.
Caveat: I consider the rule domain specific, so I think it is not correct to put it in application layer.
So what would be the best option, or is there some totally different variant?
My suggestion would be to go with your third option: Authorise access in the application/integration layer and then call into the domain.
This goes for any domain functionality really. The domain should not concern itself with whether the action may or may not be performed based on authorisation but rather only with domain concerns. If that authorisation action happens to be a domain concern in a particular Identity & Access Control bounded context that it would make sense but you would not run into those too often.

Is there anything out there to help handle "field level" authorization for ASP.NET MVC3?

I know you can use the Authorize attribute to control access to a Controller or ActionMethod... but what about more fine grained control? It seems common to have specific fields be allowed/disallowed based on a user's role, for instance. Maybe on an employee profile the employee can edit his profile information, but only a supervisor can change his job title...
Optimally I'd like to be able to develop views, models and controllers normally and have a configuration page on the website that site admins could then use to configure authorization at whatever granularity is required. In other words the programmers shouldn't worry about it (except for the guy writing/integrating that specific part of the system.)
I can envision DisplayFor and EditorFor checking attributes to render fields as ReadOnly, Hidden, etc... and maybe the attributes get added at run time from an Authorization Provider of some kind.
The question is: Is there a framework or something out there that already does this?
Write a custom ModelMetaDataProvider that will allow you to alter the metadata for each model and it's properties before they make it to the view. The built in helpers will not render a field if it's metadata value ShowForEdit = false or ShowForDisplay = false.
You can utilize a rules engine or some other ACL to manipulate the metadata on each model and property to get most of the behavior your looking for out of the box without touching the built in helpers. On edge cases where you need more control you can write your own helpers and pass more complex data in the metadata.AdditionalValues dictionary.
You can implement security at field level using HtmlHelper. In the following example they used textbox only implementation but it can easily be extended for all type of controls:
http://bartreyserhove.blogspot.ca/2008/12/field-level-security-using-aspnet-mvc.html

Spring ACL questions

I am using the new Spring Security 3.1 and have a few questions to Spring Security ACL.
So let's say I have an object and want to define an ACL for it. I create an ACL Entry and want to asign it to a group of users; not a role (GrantedAuthoritySid), not one user (PrincipalSid), but a group of users. I have researched everywhere for an example but was unable to find any. Can you please point me to an example or the class that would help me in this scenario?
So now I want to create a second object that is related to the first object (it should apply for the same users).
This could be a status update for the first object for example. My GrantedAuthority or Principal has a different mask of permisions for the second object.
Also the first object has 2 GrantedAuthorities (2 ACLEntries), and the status update has just one. If I use ACL inheritance the permision sets for the first object do not match the permision set for the second.
My question is how can I model this so that the GrantedAuthorities for the two objects are automatically kept consistent while retaining different permision masks. One idea is to use a composite pattern to link the GrantedAuthority of the second object on the GrantedAuthority of the first object (instead of linking it to users).
An ACL has a owner. What is the owner for? What role does it play for the ACL or for the ACL entries?
It's kind of complicated. I reverse engineered the Spring source code to understand the principle and it took me a lot of time. I can't exactly tell you how I implemented it (because it's very specific for the project I work on) but will try to give you a starting point.
What I did was:
Implement a custom org.springframework.security.acls.sid.Sid. This Sid references not an authority or user but a kind of groupobject which has an id and references two different objects. To use this groupobject as an Sid you have to create an ACL_Sid-record with the id of the object as ACL_sid.sid. ACL_sid.principal has to be an integer other than 0 or 1 which has to be checked for in a test in the custom LookupStrategy (see below and the Spring sourcecode).
Extend org.springframework.security.acls.sid.SidRetrievalStrategyImpl to retrieve the custom Sid's from the database.
Implement a custom org.springframework.security.acls.jdbc.LookupStrategy. I copied an existing implementation (because the class was final) and modified it for my needs.
Wired everything together in the spring configuration because the default Spring ACL config needs to no which classes it had to use (and not the defaults)
Look at the Spring source code and see how it's done.
To assign an object to a group of users, there should be an ACL entry for each user for the same object. This may lead to a considerably large amount of ACL records.

Is it possible to set a scope to a domain class?

I'd like to know if it's possible with grails to specify a scope for the domain classes.
Few words to explain how my application is working at the moment:
- database access is done through an external "module" using SQLJ. This module is user by controllers in my grails app.
- a user ask for specific information submitting forms -> request submitted to the external module -> information extracted from the database -> information loaded into grails mem DB (HSQL) -> information displayed in views.
It works fine in development environment as i'm the only one using the application. But i'm wondering how the application would behave with two or more users. I mean, do the information loaded into grails memory database will be shared between users or not? And how not to shared information requested by one user with the others?
Thanks in advance for any help about this subject.
Regards.
All data in the database is shared across all users of the grails application. You would have to write a custom query to limit the data returned to a specific user. Based on your application maybe something similar to the following.
class DomainClass1 {
//fields you get from SQLJ go here
int userId
}
To get data into an instance of your domain class.
def domInstance=new DomainClass1()
domInstance.loadFromSQLJ() //call the SQLJ module and put it's data in the domain class
domInstance.userId=5 //assign the user associated with this info
domInstance.save()
Then when you want to display info for the user with the userId 5
def domInstance2=DomainClass1.findByUserId(5)
//Do stuff with domInstance2
It will be shared between all users.
But it depends on you, as for any other database, there must be some criteria (db column) by which you can choose only information related to current user.
In our project, we overrode domain classes' get(), list() that take into account domain aggregate root (a User or whatever), and also check all the named queries.
This leaves off all the other means of accessing instances, like findBy*(), criteria, findWhere() (though you can also override the dynamic methods), or HQL, but anyway reduces the amount of security review by 80%.
Suddenly it turned out to be OK to use DomainClass.list() in scaffolding.

ACL on field level in Grails

in our new software project, we have the following requirement: A webpage shall show a set of data. This data shall be editable by some users (assigned to roles, i.e. manager), and only viewable by others. The tricky part is described by an example:
A User-page consists of address data and account information. The addess data shall be editable by the user and the manager and viewable by all users, while account information shall only be viewable by the actual user and the manager.
I have read a lot of information about SpringSecurity. It provides a very good framework to gran permissions on urls and methods and even domain classes. But what I need is field level ACLs. At least, that's what I think at the moment.
So, the question is: How to solve this problem using Grails?
Thanks a lot in advance,
Regards Daniel
Spring Security (Acegi Plugin) is definitely the way to go with Grails.
There is a taglib you can use that will allow a page to be different for different roles such as the following:
<g:ifUserHasRole roles="ROLE_ADMIN">
html code for extra fields
</g:ifUserHasRole>
Me, I'd encode it on the domain class, emulating the way GORM has you annotate the domain classes (static access = [field1: "ROLE_USER", field2: "ROLE_ADMIN,ROLE_USER"] as an example). Then build a method your controller could use to redact them for a given user. That method could use the domain class's annotations to decide how to redact it. Then, metaprogram it onto each of the domain classes the way plugins do.
Similarly, write the opposite method to restrict data bindings of params into the domain class, write your own data binding utility method, then metaprogram it onto each domain class as well.
Then you can just use instance.redact(user) or instance.bindData(params, user) to do what you want, and it's practically declarative syntax.
We have a similar situation and use both the ifUserHasRole tag in the gsp to drive the appropriate presentation and the we have a filter that enforces the rules based on the action being called. For example, on user controller we would only allow the management roles to call save action, or if the user.id is the same as the session.user.id. This seemed to be the best option for our situation.
What about creating an ACL class like this:
class ACL(val entry: Entry*) {
def isAccessAllowed(subject: String, permission: String): Boolean = ...
}
class Entry(val subject: String, val permission: String*)
usage:
new ACL(
new Entry("dave", "read", "write"),
new Entry("linda", "read")
)
(This example is in Scala, because I found it more expressive in this case, but it should be easy to transfer it to Groovy.)
You would then connect an ACL object with the object to be protected.

Resources