Created
February 27, 2014 15:57
-
-
Save tobnee/9252893 to your computer and use it in GitHub Desktop.
A simple way to use Play Filters to enforce some basic authentication rules. Based on this pattern more elaborate rules can be implemented.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Global extends WithFilters( | |
new OpenIdAuthFilter, | |
new RoleBasedPathAccessFilter(a => Some(User("user", "ADMIN")), "ADMIN", routes.Admin.index()) | |
) { | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class User(mail: String, role: String) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import play.api.mvc._ | |
import play.api.libs.concurrent.Execution.Implicits.defaultContext | |
import play.api.libs.iteratee.Iteratee | |
import controllers.routes | |
/** | |
* Ensure that user is logged in before any call can go though. | |
* The only valid paths before log in are the login page and | |
* the OpenID callback | |
*/ | |
class OpenIdAuthFilter extends EssentialFilter { | |
val openIdCallbackPath = routes.Application.openIDCallback | |
val loginPath = routes.Application.login() | |
val loginPaths = Set(openIdCallbackPath.url, loginPath.url) | |
def apply(next: EssentialAction): EssentialAction = new EssentialAction { | |
def apply(request: RequestHeader) = { | |
if (!loginPaths.contains(request.path) && request.session.get("email").isEmpty) { | |
Iteratee.ignore[Array[Byte]].map(_ => Results.Redirect(loginPath)) | |
} else { | |
next(request) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import play.api.mvc._ | |
import play.api.libs.iteratee.Iteratee | |
import scala.concurrent.ExecutionContext | |
import ExecutionContext.Implicits.global | |
/** | |
* If a user enters a restricted area (e.g. /admin), check if he has the appropriate role | |
* otherwise reject the request | |
*/ | |
class RoleBasedPathAccessFilter(val userByMail: (String => Option[User]), val resRole: String, restrictedAreas: { def url: String }*) extends EssentialFilter { | |
private val restricted = restrictedAreas.map(_.url).toSet | |
def apply(next: EssentialAction): EssentialAction = new EssentialAction { | |
def apply(request: RequestHeader) = { | |
val area = request.path | |
if (restricted.contains(request.path)) { | |
if (isAuthenticated(area, request)) next(request) | |
else Iteratee.ignore[Array[Byte]].map(_ => Results.Forbidden(views.html.defaultpages.unauthorized())) | |
} else next(request) | |
} | |
} | |
def isAuthenticated(area: String, request: RequestHeader) = { | |
request.session.get("email").flatMap(userByMail) | |
.find(user => user.role == resRole) | |
.isDefined | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment