Showing posts with label jsecurity. Show all posts
Showing posts with label jsecurity. Show all posts

Monday, December 22, 2008

Grails + JSecurity

I have been using the Grails JSecurity Plugin for authentication/authorization in my proto-type Grails app.

While there are many good things about the JSecurity Grails Plugin, "thorough documentation" is not one of them. I had some difficulty figuring out how to tie it all togethr, so I am posting here my basic set up.

For apps where authorization is, to some degree, external to the core object model, the WildcardPermission is the flexible, powerful way to go.

In my app, however, authorization rules are deeply embedded within the domain model -- whether or not User X can edit object Y is a function of some of Y's member values. I do not see how that can be accomplished via WildcardPermission.

My first cut of a solution involves defining an enum and an interface


public enum PermissionActionEnum {
VIEW, EDIT, EXECUTE, DELETE, CREATE, ...
}

public interface AuthProvider<E> {
public boolean isPermitted(User u, PermissionActionEnum a, E on);
public Class<E> getClazz();
}


Each of these AuthProviders knows how to determine authorization by examining the target object. I have a class "GlobalAuthProvider" which contains references to all the known AuthProviders and its own isPermitted method which delegates appropriately.

I defined a JSecurity Permission to link resource/target with a PermissionAction.


public class ResourcePermission implements org.jsecurity.authz.Permission {
Object resource
PermissionActionEnum action
...
//So that action can be set with either an Enum or String
public void setAction(String name) {
action = PermissionActionEnum.valueOf(name.toUpperCase());
}
}


Next, I defined a groovy authService which wraps the GlobalAuthProvider


public class AuthService {
...
public boolean isPermitted(User user, ResourcePermission resourcePermission) {
GlobalAuthProvider gap = ...
Object on = resourcePermission.resource
PermissionActionEnum action = resourcePermission.action
return gap.isPermitted(user, action, on);
}
...


My Realm then delegates to the authService

class MyRealm {
def authService
...
//Assumes ResourcePermision
def isPermitted(principal, requiredPermission) {
def user = User.findByName( principal )
return authService.isPermitted(user, requiredPermission)
}
...


Now the JSecurity tag can be used in the gsp. This is a little tricky because the GSP jsec:hasPermission tag, appears to be slightly different from the general JSP one


<jsec:hasPermission
permission="${ new ResourcePermission(resource:obj,action:'VIEW') }">
...
</jsec:hasPermission>