-
Grails JSecurity Plugin version 0.4 released
Posted on August 6th, 2009 15 commentsI have finally released version 0.4 of the Grails JSecurity Plugin – see the release notes for more details.
This will be the last release under this name because JSecurity was renamed to Apache Shiro. All future work will now be done on the Shiro Plugin. You can already install a 1.0-SNAPSHOT version that is basically the JSecurity Plugin 0.4 rebadged.
Wildcard permissions
The most significant change in version 0.4 is native support for JSecurity’s WildcardPermission. “What’s that?” I hear you cry. A permission in JSecurity serves two purposes:
- it is a representation of a right or privilege that is required to access something, such as a document or a printer
- it represents one or more rights or privileges that a particular user has
So in order for a user to access a secured resource, his assigned rights must match (or “imply”) those required by the resource.
JSecurity implements permissions via an interface, called unsurprisingly Permission. You can create any type of permission you like, as long as it implements that interface. Objects get a bit clunky, though, when you start dealing with declarative access control. Consider this example access control filter:
import org.jsecurity.grails.JsecBasicPermission class SecurityFilters { def filters = { main(controller: "*", action: "*") { before = { accessControl { permission(new JsecBasicPermission(controllerName, actionName)) } } } } }This example ensures that each controller action requires the user to have a permission specific to the controller name and action name. As I said, it’s clunky.
WildcardPermission is an implementation of the Permission interface that uses a single string to describe an arbitrary permission. The string must follow a certain pattern in order for the permission to work properly, but this is best demonstrated by example. Let’s take the previous example and modify it to use a wildcard permission:
class SecurityFilters { def filters = { main(controller: "*", action: "*") { before = { accessControl { permission("$controllerName:$actionName") } } } } }We have managed to do away with the import and the permission requirement is now a simple string. The important thing to notice is that the controller and action names are separated by a colon, ‘:’. Each substring separated by a colon is called a part. As far as JSecurity and the WildcardPermission implementation are concerned, these parts have no inherent meaning. They don’t know that the first part is a controller name or that the second part is the name of an action. It’s up to the application to give the parts meaning and interpret them.
Of course, I’ve only shown you a permission requirement. How do you assign such a permission to a user? Well, assuming that you are using the default database realm that comes with the plugin, the code you need will look something like this:
class BootStrap { def init = { servletContext -> ... // Wildcard permissions. def wildcardPermission = new JsecPermission(type: "org.jsecurity.authz.permission.WildcardPermission", possibleActions: "*").save() new JsecUserPermissionRel(user: user1, permission: wildcardPermission, target: "book:list,show", actions: "*").save() new JsecUserPermissionRel(user: user2, permission: wildcardPermission, target: "book:*", actions: "*").save() ... } }As you can see, you must first create an instance of the JsecPermission domain class for WildcardPermission. You can then link this permission to users via the JsecUserPermissionRel domain class. The target contains the permission string, while the actions property is ignored.
If you take a look at the first permission assignment, you’ll see that it allows the first user to access the list and show actions on the book controller. Notice how the assignment includes the names of two actions? These are sub-parts and they are separated by commas. It’s very unusual to see sub-parts in a permission requirement, but they are common in permission assignments like this. The second user has access to all the actions courtesy of the wildcard ‘*’.
In fact, you can have as many parts and sub-parts as you need. For example, we could add an extra part to the above permissions that represented a domain instance ID.
If you want to learn more about the rules that determine whether one permission string implies another, then take a look at the Javadoc for WildcardPermission. That’s all for now folks!





Social Media