Deadbolt is an authorisation mechanism for defining access rights to certain controller methods or parts of a view using a simple AND/OR/NOT syntax.
Note that Deadbolt doesn’t provide authentication! You can use the existing authentication features of Play 2, or third-party modules such as SecureSocial alongside Deadbolt to provide authentication, and in cases where authentication is handled outside your app you can just hook up the authorisation mechanism to whatever auth system is used.
Implement DeadboltHandler. Update your application.conf to have
deadbolt.handler=fully-qualified name of your implementation
Deadbolt doesn’t cache the role holder within the same request by default. You can enable this (typically with performance benefits) by add this to application.conf
deadbolt.cache-user=true
This issue was reported in github by jblipphaus:
When getting a result through my DeadboltHandler I recognized, that the current Http.Context seems to “get lost”, for example the @Messages(“foo”) call does not work any longer. So I had to add the following to the DeadboltHandler in my project:
public Result onAccessFailure(Http.Context context, String s) {
Http.Context.current.set(context); // <-- this is needed to have a current Http.Context
return ok(views.html.index.render());
}
The same with the ‘beforeRoleCheck’ method.
At the moment, there is no open repository for Play 2 modules, so Deadbolt 2 is hosted on github. You will
need to update the Build.scala of your application to add a repository resolver for this.
The dependency declaration is
"be.objectify" %% "deadbolt-2" % "1.1.2"
The Build.scala then looks like
object ApplicationBuild extends Build {
val appName = "deadbolt-usage" val appVersion = "1.1.2"
val appDependencies = Seq( "be.objectify" %% "deadbolt-2" % "1.1.2" )
val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings( resolvers += Resolver.url("Objectify Play Repository", url("http://schaloner.github.com/releases/"))(Resolver.ivyStylePatterns) ) }
Deadbolt requires its plugin to be declared in the conf/play.plugins file. If this file doesn’t exist (it’s not created by default when you create a new project),
just create it in the conf directory first, and then add
10000:be.objectify.deadbolt.DeadboltPlugin
Play 2 executes method-level annotations before controller-level annotations. This can cause issues when, for example, you want
a particular action to be applied for method and before the method annotations. A good example is Security.Authenticated(Secured.class),
which sets a user’s user name for request().username(). Combining this with method-level annotations that require a user would fail,
because the user would not be present at the method point.
One way around this is to apply Security.Authenticated on every method, which
violates DRY and causes bloat. A better way is to use the deferred value of each annotation, and then use @DeferredDeadbolt at the controller
level to execute the method-level annotations at controller-annotation time. Since annotations are processed in order of declaration, you can
specify @DeferredDeadbolt after @Security.Authenticated and so achieve the desired effect.
NB Method-level annotations override controller-level annotations. All controller restrictions can be applied at the
controller level or method level.
Name Dynamic
Used for arbitrary security. Requires an implementation of a DynamicResourceHandler, accessible through the DeadboltHandler
Parameters
- value – the resource name
- meta – additional info passed into the DynamicResourceHandler at runtime
- content – indicates the response format in case of access failure
- handler – a specific DeadboltHandler to use for this restriction, which overrides the application-standard handler
Examples
@Dynamic("foo", "hurdy:gurdy")
@Dynamic(name="foo", meta="hurdy:gurdy", content="json", handler=my.special.FunkyDeadboltHandler)
Name Restrict
Used for static security. Requires an implementation of a RoleHolder, accessible through the DeadboltHandler. Role names are ANDed together.
Parameters
- value – the ANDed role names
- content – indicates the response format in case of access failure
- handler – a specific DeadboltHandler to use for this restriction, which overrides the application-standard handler
- deferred – defer the execution until a @DeferredDeadbolt annotation is hit. See deferred annotations for further details.
Examples
@Restrict("foo") // restricts access to RoleHolders with the foo role
@Restrict({"foo", "bar"}) // restricts access to RoleHolders with both the foo and bar roles
Name Restrictions
Used for static security. Requires an implementation of a RoleHolder, accessible through the DeadboltHandler. Role names are ANDed together within And annotations, and ORed together between And annotations.
Parameters
- value – the restriction combinations
- content – indicates the response format in case of access failure
- handler – a specific DeadboltHandler to use for this restriction, which overrides the application-standard handler
- deferred – defer the execution until a @DeferredDeadbolt annotation is hit. See deferred annotations for further details.
Examples
@Restrictions({@And("foo"), @And("bar")}) // restricts access to RoleHolders with either the foo or bar roles
Name Unrestricted
Used for Marks the resource as unrestricted – no role checking, or presence of a role holder, is required
Parameters
- content – indicates the response format in case of access failure
- handler – a specific DeadboltHandler to use for this restriction, which overrides the application-standard handler
- deferred – defer the execution until a @DeferredDeadbolt annotation is hit. See deferred annotations for further details.
Examples
@Unrestricted
Name RoleHolderPresent
Used for Marks the resource as restricted, but only to logged-in users
Parameters
- content – indicates the response format in case of access failure
- handler – a specific DeadboltHandler to use for this restriction, which overrides the application-standard handler
- deferred – defer the execution until a @DeferredDeadbolt annotation is hit. See deferred annotations for further details.
Examples
@RoleHolderPresent
Name RoleHolderNotPresent
Used for Marks the resource as restricted, but only to not-logged-in users
Parameters
- content – indicates the response format in case of access failure
- handler – a specific DeadboltHandler to use for this restriction, which overrides the application-standard handler
- deferred – defer the execution until a @DeferredDeadbolt annotation is hit. See deferred annotations for further details.
Examples
@RoleHolderNotPresent
Name DeadboltPattern
Used for Evaluating exact matches, regular expressions or custom values against user permissions
Parameters
- value – the pattern
- patternType – indicates the type of pattern, either EQUALITY, REGEX or CUSTOM. EQUALITY is the default value.
- content – indicates the response format in case of access failure
- handler – a specific DeadboltHandler to use for this restriction, which overrides the application-standard handler
- deferred – defer the execution until a @DeferredDeadbolt annotation is hit. See deferred annotations for further details.
Examples
bc. @DeadboltPattern(“(.)*\\.edit”)
Name DeferredDeadbolt
Used for If any method-level annotations are deferred, using this annotation on the controller will execute them once the controller annotations are executed.
Examples
bc. @DeferredDeadbolt
Notes:
- Regular expressions are cached for efficiency
If you don’t want to use the full namespace of the tags, you can import some or all of them in your template. For each tag, there is a variant
ending in Or (e.g. restrictOr, dynamicOr) that takes a second block of HTML that will be inserted into the document if the check fails.
@import be.objectify.deadbolt.views.html._
Name restrict
Used for static security. This is the view equivalent of @Restrictions.
Parameters
- roles – a List of String arrays. Roles within an array are ANDed together; Each array represents an OR.
Examples
@restrict(la(as("foo"))) {
foo
}
@restrictOr(la(as("foo"))) {
foo
}{Failure content}
Notes:
As a convenience to create the lists and arrays, you can import the methods of TemplateUtils and use the following methods
– la – create a list of arrays
– as – create an array of strings
You can see this used in the example above. A more detailed example is
@deadbolt.restrict(la(as("foo"),as("bar"))) {
foo
}
@deadbolt.restrictOr(la(as("foo"),as("bar"))) {
foo
}{Failure content}
You can import these methods into your templates with @import be.objectify.deadbolt.utils.TemplateUtils._
Name dynamic
Used for arbitrary security. This is the view equivalent of @Dynamic
Parameters
- name – the resource name
- meta – additional info passed into the DynamicResourceHandler at runtime
Examples
@dynamic("foo") {
foo
}
@dynamic("bar", "hurdy:gurdy") {
bar
}
@dynamicOr("bar", "hurdy:gurdy") {
bar
}{Failure content}
Name roleHolderPresent
Used for ensuring the viewer is logged in. This is the view equivalent of @RoleHolderPresent
Parameters
- name – the resource name
- meta – additional info passed into the DynamicResourceHandler at runtime
Examples
@roleHolderPresent {
foo
}
@roleHolderPresentOr {
foo
}{Failure content}
Name roleHolderNotPresent
Used for ensuring the viewer is not logged in. This is the view equivalent of @RoleHolderNotPresent
Parameters
- name – the resource name
- meta – additional info passed into the DynamicResourceHandler at runtime
Examples
@roleHolderNotPresent {
foo
}
@roleHolderNotPresentOr {
foo
}{Failure content}
Name deadboltPattern
Used for checking exact matches, regexs or custom values against user permissions. This is the view equivalent of @DeadboltPattern
Parameters
- value – the pattern value
- patternType – the pattern type, e.g. EQUALITY, REGEX, CUSTOM
Examples
@deadboltPattern("(.)*\\.edit") {
foo
}
@deadboltPattern("(.)*\\.edit", PatternType.REGEX) {
foo
}
@deadboltPatternOr("(.)*\\.edit", PatternType.REGEX) {
foo
}{Failure content}
Note There is no tag equivalent of @Unrestricted