views:

209

answers:

4

Hello,

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

A: 

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>
Sean A.O. Harney
Thanks for that incredible fast answer.This tag seems to very helpful as limited views and propably edit functionality can be implemented by using it. The only drawback which occurs to me is: Roles are hardcoded in the GSP-files, aren't they? Do you have some clever hint for this issue, too?
Daniel
In Bootstrap.groovy you usually have some code to define the roles and .save() but GORM (with sql) actually creates some database tables such as role.
Sean A.O. Harney
Thanks again for your answer.One question concerning security: If viewing or editing of a property is disabled, this does not mean that the controller "knows" about the fact and ignores some data which is sent in the request. So what is the best practice to prevent such an "attack". In addition, it seems to me that I have to hardcode the role mapping to a property on two places: GSP and the controller. Is there any central place to put it?
Daniel
I don't think the Spring Security plugin has ACL support yet?
Kimble
@kimble Yes it isn't ACL, but role based access control seems to be what he wants.
Sean A.O. Harney
A: 

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.

John Stoneham
A: 

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.

JeffSea
A: 

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.

deamon

related questions