Pac4j Play Integration
The goal of this project is to create a well documented playground for pac4j authentication and authorization with Play.
The main concepts in pac4j are:
- a client: that represents an authentication mechanism. It performs the login process and returns a user profile.
- an authenticator: is required by HTTP clients to validate provided credentials.
- an authorizer: that checks if the given profile has the rights to access a requested resource.
- a matcher: defines a (regular) expression that is applied on security filters
- a config: which defines the security configurations via clients, authorizers and matchers
1. Clients
Clients can be categorized into:
- direct client: such as web services o HTTP clients, which negotiate the access directly.
- indirect client: that uses redirects to a third party service to perform the login (e.g. facebook, google, twitter) More details about them can be found here
The first category is for web service authentication, where the credentials happens for each http request (stateless). The second category if for UI authentication and the login happens once per session (stateful).
The supported clients are listed here.
While most clients are self-sufficient, the HTTP clients require defining an Authenticator to handle the credentials validation.
In this playground we are interested in:
- basic auth (using both indirect (IndirectBasicAuthClient) and direct (DirectBasicAuthClient) clients).
- cookie client: CookieClient value sent as a cookie
- header client: HeaderClient value sent as a HTTP header
- parameter client: ParameterClient value sent as a HTTP parameter
Clients (like Authorizers) are generally defined in a security configuration.
2. Authenticator
It is used by Clients (see above) to validate credentials and create a user profile. The Authenticator
interface has only one method
def validate(c: Credentials, context: WebContext): Unit {
}
Credentials provided via clients can be of two types:
- username/password UsernamePasswordCredentials
- tokens Token Credentials such as JWT
We can define different Authenticators, but we are interested on: - LDAP - JWT - REST API
Recommendations:
- use a LocalCachingAuthenticator to cache the requests made to the identity provider. It uses guava but it can be modified to use another store.
3. Authorizer
It checks if a user profile extracted by a client has the authorization to access the requested resource.
Urls can be protected via:
- Secure annotation on controllers methods
def basicSecured() = Secure("DirectBasicAuthClient") { profiles =>
actionBuilder { request =>
Ok(views.html.protectedpage(profiles))
}
}
- Security filter defined in the
application.conf
file
pac4j.security {
rules = [
{"/profile" = {
authorizers = "_authenticated_"
clients = "DirectBasicAuthClient"
}}
]
}