pac4j
is a Java authentication / authorization engine to authenticate users, get their profiles and manage their authorizations in order to secure your Java web applications. It's available under the Apache 2 license.
It is actually implemented in many frameworks and supports many authentication mechanisms. See the big picture.
They depend on the pac4j-core
module (groupId: org.pac4j
):
- the SSO CAS server using the cas-server-support-pac4j module (demo: cas-pac4j-oauth-demo)
- the Play 2.x framework using the the play-pac4j library (demos: play-pac4j-java-demo & play-pac4j-scala-demo)
- any J2E environment using the j2e-pac4j library (demo: j2e-pac4j-demo)
- the Apache Shiro project library using the buji-pac4j library (demo: buji-pac4j-demo)
- the Spring Security library using the spring-security-pac4j library (demo: spring-security-pac4j-demo)
- the Ratpack JVM toolkit using the ratpack-pac4j module (demo: ratpack-pac4j-demo)
- the Vertx framework using the vertx-pac4j module (demo: vertx-pac4j-demo)
- the Undertow web server using the undertow-pac4j module (demo: undertow-pac4j-demo)
- the Spark Java framework using the spark-pac4j library (demo: spark-pac4j-demo)
- the Jooby framework using the jooby-pac4j module (demo: jooby-pac4j-demo)
pac4j
supports stateful and stateless authentication flows using external identity providers or direct internal credentials authenticator and user profile creator:
- OAuth (1.0 & 2.0): Facebook, Twitter, Google, Yahoo, LinkedIn, Github... using the
pac4j-oauth
module - CAS (1.0, 2.0, SAML, logout & proxy) + REST API support using the
pac4j-cas
module - HTTP (form, basic auth, IP, header, GET/POST parameter authentications) using the
pac4j-http
module - OpenID using the
pac4j-openid
module - SAML (2.0) using the
pac4j-saml
module - Google App Engine UserService using the
pac4j-gae
module - OpenID Connect 1.0 using the
pac4j-oidc
module - JWT using the
pac4j-jwt
module.
See all authentication mechanisms.
Read the appropriate documentation for the SSO CAS server, Play 2.x framework, J2E, Apache Shiro, Spring Security, Ratpack, Vertx, Undertow, Spark Java framework or Jooby. See the "Frameworks / tools implementing pac4j
".
The current version 1.8.0-SNAPSHOT is under development. Maven artefacts are built via Travis: and available in the Sonatype snapshots repository. See the tests strategy.
The source code can be cloned and built locally via Maven:
git clone git@github.com:pac4j/pac4j.git
cd pac4j
mvn clean compile
The latest released version is the , available in the Maven central repository. See the release notes.
pac4j
is a powerful yet easy security engine which can be used in many ways.
Add the pac4j-core
dependency to benefit from the core API of pac4j
. Other dependencies will be optionally added for specific support: pac4j-oauth
for OAuth, pac4j-cas
for CAS, pac4j-saml
for SAML...
To secure your Java web application, a good implementation is to create two filters: one to protect urls, the other one to receive callback calls for stateful authentication processes ("indirect clients").
Gather all your clients via the Clients
class to share the same callback url:
FacebookClient facebookClient = new FacebookClient(FB_KEY, FB_SECRET);
TwitterClient twitterClient = new TwitterClient(TW_KEY, TW_SECRET);
FormClient formClient = new FormClient("http://localhost:8080/theForm.jsp", new SimpleTestUsernamePasswordAuthenticator(), new UsernameProfileCreator());
CasClient casClient = new CasClient();
casClient.setCasLoginUrl("http://mycasserver/login");
Clients clients = new Clients("http://localhost:8080/callback", facebookClient, twitterClient, formClient, casClient);
In your protection filter, you may implement this simple logic:
EnvSpecificWebContext context = new EnvSpecificWebContex(...);
EnvSpecificProfileManager manager = new EnvSpecificProfileManager(...);
UserProfile profile = manager.get();
if (profile != null) {
grantAccess();
} else {
saveRequestedUrl();
Client client = clients.findClient(configName);
try {
client.redirect(context);
} catch (RequiresHttpAction e) {
handleSpecialHttpBehaviours();
}
}
The EnvSpecificWebContext
and EnvSpecificProfileManager
classes are specific implementations of the WebContext
and ProfileManager
interfaces for your framework.
With pac4j
version 1.8 which supports direct authentication (REST) and authorizations, you can use a more evolved algorithm:
EnvSpecificWebContext context = new EnvSpecificWebContex(...);
EnvSpecificProfileManager manager = new EnvSpecificProfileManager(...);
UserProfile profile = manager.get();
Client client = clients.findClient(context);
if (client == null) {
client = clients.findClient(configName);
}
boolean isDirectClient = client instanceof DirectClient;
if (profile == null && isDirectClient) {
try {
credentials = client.getCredentials(context);
} catch (RequiresHttpAction e) { }
profile = client.getUserProfile(credentials, context);
if (profile != null) {
manager.save(profile);
}
}
if (profile != null) {
if (configAuthorizer.isAuthorized(context, profile) {
grantAccess();
} else {
errorHttp403Forbidden();
}
} else {
if (isDirectClient) {
errorHttp401NotAuthenticated();
} else {
saveRequestedUrl();
try {
client.redirect(context);
} catch (RequiresHttpAction e) {
handleSpecialHttpBehaviours();
}
}
}
In your callback filter:
EnvSpecificWebContext context = new EnvSpecificWebContex(...);
EnvSpecificProfileManager manager = new EnvSpecificProfileManager(...);
Client client = clients.findClient(context);
Credentials credentials;
try {
credentials = client.getCredentials(context);
} catch (RequiresHttpAction e) {
handleSpecialHttpBehaviours();
}
UserProfile profile = client.getUserProfile(credentials, context);
if (profile != null) {
manager.save(profile);
}
redirectToTheOriginallyRequestedUrl();
Browse some code samples and the technical components.
- Client: a client is a way to authenticate, it is responsible for starting the authentication process if necessary (stateful use case), validating the user credentials and getting the user profile (all cases). A hierarchy of user profile exists: DirectClient, IndirectClient, FacebookClient, CasClient...
- Clients: it's a helper class to define all clients together and reuse the same callback url
- UserProfile: it's the profile of an authenticated user. A hierarchy of user profiles exists: CommonProfile, OAuth20Profile, FacebookProfile...
- AttributesDefinition: it's the attributes definition for a specific type of profile
- ProfileManager: it's a manager to get/set/remove the current user profile
- Credentials: it's a user credentials. A hierarchy of credentials exists: CasCredentials, Saml2Credentials, UsernamePasswordCredentials...
- WebContext: it represents the current HTTP request and response, regardless of the framework
- AuthorizationGenerator: it's a class to compute the roles and permissions for a user profile
- Authorizer: it's a generic concept to manage authorizations given a user profile and a web context
- Extractor: it's a way to get user credentials from a HTTP request
- Authenticator: it's the interface to implement to validate user credentials. Several implementations exist
- ProfileCreator: it's the interface to implement to create a user profile from credentials. Several implementations exist.
If you have any question, please use the following mailing lists: