Skip to content

Advanced: Action composition

Camilo A. Sampedro Restrepo edited this page Jan 13, 2017 · 3 revisions

Action composition

play2.auth use stackable-controller

Suppose you want to validate a token at every action in order to defeat a Cross Site Request Forgery attack.

Since it is impractical to perform the validation in all actions, you would define a trait like this:

trait TokenValidateElement extends StackableController {
    self: Controller =>

  private val tokenForm = Form("token" -> text)

  private def validateToken(request: Request[AnyContent]): Boolean = (for {
    tokenInForm <- tokenForm.bindFromRequest(request).value
    tokenInSession <- request.session.get("token")
  } yield tokenInForm == tokenInSession).getOrElse(false)

  override proceed[A](reqest: RequestWithAttributes[A])(f: RequestWithAttributes[A] => Result): Result = {
    if (validateToken(request)) super.proceed(request)(f)
    else BadRequest
  }

}

You can use TokenValidateElement trait with AuthElement trait.

object Application extends Controller with TokenValidateElement with AuthElement with AuthConfigImpl {

  def page1 = StackAction(AuthorityKey -> NormalUser) { implicit request =>
    // do something
    Ok(html.page1("result"))
  }

  def page2 = StackAction(AuthorityKey -> NormalUser) { implicit request =>
    // do something
    Ok(html.page2("result"))
  }

}