Deadbolt 2 Scala

This is a collection of examples using Deadbolt 2 at both the controller and template level to implement authorisation in a Play 2 application.

Configuration

For the purposes of these examples, except where stated otherwise, the user has the following roles:

  • foo
  • bar

The user also has the following permissions:

  • printers.edit

Controller authorisation

Protecting your controllers against unauthorised use is a key element of good application security. Here, you'll find examples of each of the controller-level authorisations provided by Deadbolt 2.

For each example, the action is shown on the left, and the result is loaded into an iframe on the right.

SubjectPresent

This is one of the simplest constraints in Deadbolt. It simply requires that a user be present (i.e. logged in).

Specification
Result
SubjectPresent(new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
SubjectPresent(new MyUserlessDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}

SubjectNotPresent

The counterpart to SubjectPresent. This constraint requires that a user isn't present (i.e. no-one is logged in).

Specification
Result
SubjectNotPresent(new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
SubjectNotPresent(new MyUserlessDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}

Restrict

Restrict uses an ANDed set of roles to determine access to an action. For example, a user with the roles "foo" and "bar" could access a Restrict-protected action that specified any of the following:

  • foo
  • bar
  • foo AND bar

However, a Restrict that required "foo", "bar" and "hurdy" would deny access to the user.

Specification
Result
Restrict(Array("foo"), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Restrict(Array("foo", "bar"), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Restrict(Array("foo", "!bar"), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Restrict(Array("hurdy"), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}

Restrictions

A Restrictions constraint allows you to OR role groups together. For example, you could allow access to a user that matches at least one of the following restrictions:

  • foo
  • hurdy AND gurdy
Specification
Result
Restrictions(List(Array("foo", "bar")), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Restrictions(List(Array("foo"), Array("bar")), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Restrictions(List(Array("hurdy", "gurdy"), Array("foo")), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Restrictions(List(Array("foo"), Array("!bar")), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Restrictions(List(Array("hurdy", "foo")), new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}

Dynamic

Dynamic is the most powerful constraint in Deadbolt. It enforces arbitrary rules. See the documentation for a full overview.

In these examples, the action is shown on the left, the rule specified in the relevant DynamicResourceHandler is in the center and the result is in an iframe on the right.

Specification
Rule
Result
Dynamic("pureLuck",
        "",
        new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
def isAllowed[A](name: String,
                 meta: String,
                 deadboltHandler: DeadboltHandler,
                 request: Request[A]) =
  System.currentTimeMillis() % 2 == 0
Dynamic("pureLuck",
        "",
        new MyDeadboltHandler(
            MyAlternativeDynamicResourceHandler)) {
  Action {
    Ok(accessOk())
  }
}
  def isAllowed[A](name: String,
                   meta: String,
                   deadboltHandler: DeadboltHandler,
                   request: Request[A]) = false

Pattern

Pattern allows you to use regular expressions to determine access.

Specification
Result
Pattern("printers.edit",
        PatternType.EQUALITY,
        new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Pattern("printers.foo",
        PatternType.EQUALITY,
        new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}
Pattern("(.)*\\.edit",
        PatternType.REGEX,
        new MyDeadboltHandler) {
  Action {
    Ok(accessOk())
  }
}

Template authorisation

Deadbolt tags does not offer any real protected against misuse on your server side, but it does allow you to customise your UI according to the privileges of the current user.

Each tag has an "Or" variant, e.g. restrictOr, that allows you to pass in a alternative body for when authorisation fails.

For each example, the unprotected content is on the left, the Deadbolt tag is in the center and the result of the authorisation is on the right.

subjectPresent

This is one of the simplest constraints in Deadbolt. It simply requires that a user be present (i.e. logged in).

Unprotected content
Specification
Result
This content should be visible
@subjectPresent(handler) {
  This content should be visible
}
This content should be visible
This content should NOT be visible
@subjectPresent(new security.MyUserlessDeadboltHandler) {
  This content should NOT be visible
}
This content should be visible
@subjectPresentOr(handler) {
  This content should be visible
}{Sorry, no access}
This content should be visible
This content should NOT be visible
@subjectPresentOr(new security.MyUserlessDeadboltHandler) {
  This content should be NOT visible
}{Sorry, no access}
Sorry, no access

subjectNotPresent

The counterpart to subjectPresent. This constraint requires that a user isn't present (i.e. no-one is logged in).

Unprotected content
Specification
Result
This content should NOT be visible
@subjectNotPresent(handler) {
  This content should NOT be visible
}
This content should be visible
@subjectNotPresent(new security.MyUserlessDeadboltHandler) {
  This content should be visible
}
This content should be visible
This content should NOT be visible
@subjectNotPresentOr(handler) {
  This content should NOT be visible
}{Sorry, no access}
Sorry, no access
This content should be visible
@subjectNotPresentOr(new security.MyUserlessDeadboltHandler) {
  This content should be visible
}{Sorry, no access}
This content should be visible

restrict

restrict uses an ANDed set of roles within an array to determine if a part of a template is rendered. For example, a user with the roles "foo" and "bar" could see a restrict-protected area of template that required any of the following:

  • foo
  • bar
  • foo AND bar

However, a restrict that required "foo", "bar" and "hurdy" would not render the protected area.

Giving multiple arrays in the list gives the equivalent of the Restrictions controller action.

As a convenience for creating Array[String] instances, you can use the TemplateUtils#as(String...) method.

Unprotected content
Specification
Result
This content should be visible
@restrict(handler, List(as("foo", "bar"))) {
  This content should be visible
}
This content should be visible
This content should NOT be visible
@restrict(handler, List(as("foo", "bar", "hurdy"))) {
  This content should NOT be visible
}
This content should be visible
@restrict(handler, List(as("hurdy"), as("foo", "bar"))) {
  This content should be visible
}
This content should be visible
This content should be visible
@restrictOr(handler, List(as("foo", "bar"))) {
  This content should be visible
}{Sorry, you're not allowed to see this}
This content should be visible
This content should NOT be visible
@restrictOr(handler, List(as("foo", "bar", "hurdy"))) {
  This content should NOT be visible
}{Sorry, you're not allowed to see this}
Sorry, you're not allowed to see this

dynamic

dynamic is the most powerful constraint in Deadbolt. It enforces arbitrary rules. See the documentation for a full overview.

Unprotected content
Specification
Result
This content may be visible, depending on your luck
@dynamic(handler, "pureLuck") {
  This content may be visible, depending on your luck
}
This content should NOT be visible
@dynamic(new MyDeadboltHandler(MyAlternativeDynamicResourceHandler), "pureLuck") {
  This content should NOT be visible
}
This content may be visible, depending on your luck
@dynamicOr(handler, "pureLuck") {
  This content may be visible, depending on your luck
}{Guess you were unlucky}
Guess you were unlucky
This content should NOT be visible
@dynamicOr(new MyDeadboltHandler(MyAlternativeDynamicResourceHandler), "pureLuck") {
  This content should NOT be visible
}{Guess you were unlucky}
Guess you were unlucky

pattern

pattern allows you to use regular expressions to determine access.

Unprotected content
Specification
Result
This content should be visible
@pattern(handler, "printers.edit") {
  This content should be visible
}
This content should be visible
This content should NOT be visible
@pattern(handler, "printers.foo") {
  This content should not visible
}
This content should be visible
@pattern(handler, "(.)*\\.edit", PatternType.REGEX) {
  This content should not visible
}
This content should be visible