Play Framework Authentication
Authentication Library
Play Framework Authentication
Overview
Play Framework Authentication is a built-in feature for implementing web application authentication in Play Framework applications. It provides basic authentication and authorization capabilities, with support for custom authentication scheme implementations.
Details
Play Framework Authentication is a simple and lightweight authentication system built into the Play Framework. While the framework doesn't provide a complete authentication mechanism out of the box, developers need to implement their own, but essential basic components are provided. Using Security.Authenticator patterns and Secure modules, you can implement basic security features like session management, CSRF protection, and XSS prevention. As of 2024, it's still possible to build robust authentication systems following security best practices, with flexible implementation according to custom requirements. It supports both Scala and Java languages and handles authentication for both RESTful APIs and web applications.
Pros and Cons
Pros
- Framework Integration: Complete integration with Play Framework for consistent development experience
- Session Management: Secure session management with signed sessions (non-encrypted)
- CSRF Protection: Built-in Cross-Site Request Forgery (CSRF) protection
- Customizable: Flexible implementation of authentication schemes according to requirements
- Performance: Lightweight and fast authentication processing
- Security: Automatic XSS escaping and security headers
- Language Support: Support for both Scala and Java
Cons
- Basic Features Only: Advanced authentication features need to be implemented manually
- No Session Encryption: Session data is signed but not encrypted
- External Dependencies: Complex authentication requirements need external libraries
- Learning Curve: Need to learn Play Framework-specific authentication patterns
- OAuth Support: OAuth/OpenID requires separate implementation or other libraries
Key Links
- Play Framework Official Site
- Play Framework Security Guide
- Play Framework GitHub Repository
- Play Framework Security Documentation
- Play Framework Authentication Examples
Usage Examples
Basic Authenticator Implementation
// Scala authentication implementation
import play.api.mvc._
import play.api.mvc.Security.Authenticator
class MyAuthenticator extends Authenticator {
def getUsername(request: RequestHeader): Option[String] = {
// Get username from session
request.session.get("username")
}
def onUnauthorized(request: RequestHeader): Result = {
// Redirect when unauthorized
Results.Redirect(routes.AuthController.loginPage())
}
}
// Usage in controller
@Security.Authenticated(new MyAuthenticator)
def protectedAction = Action { implicit request =>
Ok(s"Hello, ${request.username}")
}
Session Management and Login
// Login processing
def login = Action { implicit request =>
loginForm.bindFromRequest.fold(
formWithErrors => {
BadRequest(views.html.login(formWithErrors))
},
userData => {
// User authentication processing
if (authenticateUser(userData.email, userData.password)) {
Redirect(routes.Dashboard.index())
.withSession("username" -> userData.email)
} else {
BadRequest(views.html.login(loginForm.withGlobalError("Invalid credentials")))
}
}
)
}
// Logout processing
def logout = Action {
Redirect(routes.AuthController.loginPage())
.withNewSession
.flashing("info" -> "You have been logged out")
}
CSRF Protection Implementation
// CSRF token generation and verification
import play.filters.csrf._
def form = Action { implicit request =>
Ok(views.html.form()(request, messagesProvider))
}
def submitForm = Action { implicit request =>
// CSRF filter automatically validates
CSRF.getToken match {
case Some(token) =>
// Form processing
processForm(request)
case None =>
Forbidden("CSRF token missing")
}
}
Java Authentication Implementation
// Java authentication implementation
import play.mvc.*;
import play.mvc.Security.*;
public class AuthAction extends Authenticator {
@Override
public String getUsername(Context ctx) {
// Get username from session
return ctx.session().get("username");
}
@Override
public Result onUnauthorized(Context ctx) {
// Redirect when unauthorized
return redirect(routes.AuthController.login());
}
}
// Usage in controller
@Security.Authenticated(AuthAction.class)
public Result dashboard() {
String username = session("username");
return ok("Welcome, " + username);
}
Custom Authentication Scheme
// API key authentication implementation example
class ApiKeyAuthAction extends ActionBuilder[Request, AnyContent] {
override def invokeBlock[A](request: Request[A], block: Request[A] => Future[Result]): Future[Result] = {
request.headers.get("X-API-Key") match {
case Some(apiKey) if isValidApiKey(apiKey) =>
block(request)
case _ =>
Future.successful(Unauthorized("Invalid API key"))
}
}
private def isValidApiKey(key: String): Boolean = {
// API key validation logic
ApiKeyRepository.validate(key)
}
}
// Usage example
def apiEndpoint = ApiKeyAuthAction { request =>
Ok(Json.obj("data" -> "Protected API response"))
}
Security Filter Configuration
// Security configuration in application.conf
play.filters.enabled += "play.filters.csrf.CSRFFilter"
play.filters.enabled += "play.filters.headers.SecurityHeadersFilter"
play.filters.enabled += "play.filters.hosts.AllowedHostsFilter"
// CSRF configuration
play.filters.csrf {
token.name = "csrfToken"
contentType.blackList = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]
}
// Security headers configuration
play.filters.headers {
frameOptions = "DENY"
xssProtection = "1; mode=block"
contentTypeOptions = "nosniff"
contentSecurityPolicy = "default-src 'self'"
}