PlayFramework 2.5: Global CSRF Protection – Disable CSRF selectively

5 Jun
2016

This is the successor of my Post “PlayFramework 2.3: Global CSRF Protection – Disable CSRF selectively“, updated to PlayFramework 2.5!

Adjust your files like this:

1. Adjust your application.conf

play.filters.csrf.header.bypassHeaders {
Csrf-Token = "my-secret-csrf-off-switch"
}
play.http.filters=framework.Filters

2. Create your filter definitions
package framework
import javax.inject.Inject
import play.api.http.HttpFilters
import play.filters.csrf.RouteCommentExcludingCSRFFilterFacade
import play.filters.gzip.GzipFilter
class Filters @Inject()(
routeCommentExcludingCSRFFilterFacade: RouteCommentExcludingCSRFFilterFacade,
gzipFilter: GzipFilter
) extends HttpFilters {
val _filters = Seq(metricsFilter,
gzipFilter,
routeCommentExcludingCSRFFilterFacade
)
override def filters = _filters
}

3. Create your wrapper
package play.filters.csrf
import javax.inject.Inject
import play.api.mvc.{EssentialAction, EssentialFilter}
import scala.concurrent.ExecutionContext
class RouteCommentExcludingCSRFFilterFacade @Inject()(filter: CSRFFilter)(implicit ec: ExecutionContext) extends EssentialFilter {
override def apply(nextFilter: EssentialAction): EssentialAction = new EssentialAction {
import play.api.mvc._
override def apply(rh: RequestHeader) = {
if (rh.tags.getOrElse("ROUTE_COMMENTS", "").contains("NOCSRF")) {
// this is required for GET/HEAD requests with no prior HTTP-Request (like bingbot)
// so they are missing a context.
// if the rendering template is using the CSRF-token to render a form, it would blow
// up if we're not processing it through the CSRF filter
val copy: RequestHeader = rh.copy(headers = rh.headers.add(("Csrf-Token", "my-secret-csrf-off-switch")))
filter.apply(nextFilter)(copy)
} else {
filter.apply(nextFilter)(rh)
}
}
}
}

4. Annotate your route with the NOCSRF Tag
#NOCSRF
POST /search @controllers.SearchController.search()
view raw routes hosted with ❤ by GitHub

 
Enjoy!

Comment Form

top