vertx-pac4j is a Profile & Authentication Client, it's a general security library to authenticate users, get their profiles, manage their authorizations in order to secure Vert.x web applications.
Although pac4j historically targets external authentication protocols, it supports direct authentication methods as well. See the authentication flows.
- From the client application, save the requested url and redirect the user to the identity provider for authentication (HTTP 302)
- After a successful authentication, redirect back the user from the identity provider to the client application (HTTP 302) and get the user credentials
- With these credentials, get the profile of the authenticated user (direct call from the client application to the identity provider)
- Redirect the user to the originally requested url and allow or disallow the access.
Supported protocols are:
- OAuth (1.0 & 2.0)
- CAS (1.0, 2.0, SAML, logout & proxy)
- HTTP (form & basic auth authentications)
- OpenID
- SAML (2.0)
- Google App Engine UserService
- OpenID Connect 1.0
The current HTTP request contains the required credentials to validate the user identity and retrieve his profile. It works from a basic authentication.
It relies on specific Authenticator to validate user credentials and ProfileCreator to create user profiles.
Provider | Protocol | Maven dependency | Client class | Profile class |
---|---|---|---|---|
CAS server | CAS | pac4j-cas | CasClient & CasProxyReceptor | CasProfile |
CAS server using OAuth Wrapper | OAuth 2.0 | pac4j-oauth | CasOAuthWrapperClient | CasOAuthWrapperProfile |
DropBox | OAuth 1.0 | pac4j-oauth | DropBoxClient | DropBoxProfile |
OAuth 2.0 | pac4j-oauth | FacebookClient | FacebookProfile | |
GitHub | OAuth 2.0 | pac4j-oauth | GitHubClient | GitHubProfile |
OAuth 2.0 | pac4j-oauth | Google2Client | Google2Profile | |
OAuth 1.0 & 2.0 | pac4j-oauth | LinkedInClient & LinkedIn2Client | LinkedInProfile & LinkedIn2Profile | |
OAuth 1.0 | pac4j-oauth | TwitterClient | TwitterProfile | |
Windows Live | OAuth 2.0 | pac4j-oauth | WindowsLiveClient | WindowsLiveProfile |
WordPress | OAuth 2.0 | pac4j-oauth | WordPressClient | WordPressProfile |
Yahoo | OAuth 1.0 | pac4j-oauth | YahooClient | YahooProfile |
PayPal | OAuth 2.0 | pac4j-oauth | PayPalClient | PayPalProfile |
Vk | OAuth 2.0 | pac4j-oauth | VkClient | VkProfile |
Foursquare | OAuth 2.0 | pac4j-oauth | FoursquareClient | FoursquareProfile |
Bitbucket | OAuth 1.0 | pac4j-oauth | BitbucketClient | BitbucketProfile |
ORCiD | OAuth 2.0 | pac4j-oauth | OrcidClient | OrcidProfile |
Strava | OAuth 2.0 | pac4j-oauth | StravaClient | StravaProfile |
Web sites with basic auth authentication | HTTP | pac4j-http | BasicAuthClient | HttpProfile |
Web sites with form authentication | HTTP | pac4j-http | FormClient | HttpProfile |
Google - Deprecated | OpenID | pac4j-openid | GoogleOpenIdClient | GoogleOpenIdProfile |
Yahoo | OpenID | pac4j-openid | YahooOpenIdClient | YahooOpenIdProfile |
SAML Identity Provider | SAML 2.0 | pac4j-saml | Saml2Client | Saml2Profile |
Google App Engine User Service | Gae User Service Mechanism | pac4j-gae | GaeUserServiceClient | GaeUserServiceProfile |
OpenID Connect Provider | OpenID Connect 1.0 | pac4j-oidc | OidcClient | OidcProfile |
vertx-pac4j consists of two maven modules:
- Pac4j Manager module for Vertx to deploy as a busmod
- Pac4j Vertx Helper module to import as a dependency in your application Verticles
This is the pac4j manager module that allows an easy integration to all pac4j supported authentication providers (OAuth, Facebook, Twitter, CAS, SAML...).
In order to facilitate the communication between your application verticles and the module, some Java helper classes are provided (see [Pac4j Vertx Helper](#Pac4j Vertx Helper). Feel free to develop and submit helpers in other Vert.x supported languages.
A stateful authentication process requires an http session, we suggest you then to use the excellent session-manager from campudus.
You can look at a complete integration example in the pac4j vertx demo app.
When using a stateful authentication mechanism (OAuth, CAS...), this busmod requires some session mechanism like the session-manager from campudus.
The module name is org.pac4j~vertx-pac4j-module~1.1.0-SNAPSHOT
.
This busmod takes the following configuration:
{
"address": <address>,
"ebConverter": <event bus object converter class>,
"clientsConfig": {
"callbackUrl": <callbackUrl>,
"clients": {
<clients>
}
}
}
For example:
{
"address": "vertx.pac4j-manager",
"clientsConfig": {
"callbackUrl": "http://localhost:8080/callback",
"clients": {
"facebook": {
"class": "org.pac4j.oauth.client.FacebookClient",
"props": {
"key": "145278422258960",
"secret": "be21409ba8f39b5dae2a7de525484da8"
}
}
}
}
}
Let's take a look at each field in turn:
address
The main address for the busmod. Optional field. Default value isvertx.pac4j-manager
ebConverter
The class of the event bus object converter required to exchange session attributes and user profile between the application verticles and the pac4j manager module (see [Serialization Methods](#Serialization Methods)). Optional field. Default value is the Java Serialization converterclientsConfig
contains two fields: the pac4j callback url and the clients list.clients
each pair describes how to configure one pac4j client. A client has aclass
and a list ofprops
. The props relies on the setter methods of the client. In the previous example,key
indicates that the corresponding value will be set on the FacebookClient object with the methodsetKey
.
The following operations relies on a common object representing the context of the current http request: the webcontext
. The web context must have the following structure:
{
"method": <http method>, (GET, POST...)
"serverName": <server name>, (localhost)
"serverPort": <server port>, (8080)
"fullUrl": <full url>, (http://localhost:8080/index.html)
"scheme": <scheme>, (http)
"headers": <headers>, ( { "Host": "localhost:8080" } )
"parameters": <parameters>, ( { "ids": ["foo", "bar"] } )
"sessionAttributes": <session attributes> ( { "userId": "foobar" } )
}
The parameters
are multi-valued and must contain GET and POST urlencoded parameters if any.
The sessionAttributes
is a list of the attributes stored in session; they must be serialized in some way (see [Serialization Methods](#Serialization Methods)).
Redirect to the given authentication provider.
To redirect, send a JSON message to the address given by the main address of the busmod + .redirect
. For example if the main address is test.pac4jManager
, you send the message to test.pac4jManager.redirect
.
The JSON message should have the following structure:
{
"clientName": <clientName>, ("FacebookClient")
"protected": <protected>, (true)
"isAjax": <isAjax>, (false)
"webContext": <webContext>
}
If redirect is successful a reply will be returned:
{
"status": "ok",
"code": <response code>, (302)
"headers": <response headers>, ( { "Location": "http://foobar" } )
"content": <response content>, ( "hello foobar" )
"sessionAttributes": <all session attributes>
}
This message has to be used to build the http response and update the session attributes.
Build redirect urls for being authenticated by the required providers.
To login, send a JSON message to the address given by the main address of the busmod + .redirectUrls
.
The JSON message should have the following structure:
{
"clients": <clients list>, ( ["FacebookClient", "TwitterClient"] )
"webContext": <webContext>
}
If getting the redirect urls is successful the following reply will be returned:
{
"status": "ok",
<Client Name>: <redirect url>,
"sessionAttributes": <all session attributes>
}
Authenticate the current request.
To authenticate, send a JSON message to the address given by the main address of the busmod + .authenticate
.
The JSON message should have the following structure:
{
"webContext": <webContext>
}
If the authentication information in the web context are valid the following reply will be returned:
{
"status": "ok",
"userProfile": <user profile>, ( { "id": "foobar"} )
"code": <response code>, (302)
"headers": <response headers>, ( { "Location": "http://foobar" } )
"content": <response content>, ( "hello foobar" )
"sessionAttributes": <all session attributes>
}
Where userProfile
is a Json Object representing the authenticated user; it must be serialized in some way (see [Serialization Methods](#Serialization Methods)).
The Vert.x architecture requires some objects to be (de)serialized between the front verticles serving the HTTP requests and the pac4j manager module. These objects are the session attributes and the User Profile.
By default, a serialization based on Jackson is used (org.pac4j.vertx.DefaultEventBusObjectConverter
).
In order to pass in a custom converter, add the ebConverter
parameter to the pac4j manager module:
{
"ebConverter": "org.pac4j.vertx.MyCustomObjectConverter"
}
In order to facilitate the integration with the pac4j manager busmod, you can use the Pac4j Vertx Helper module.
Import the following dependency in your Vertx project:
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>vertx-pac4j-helper</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
- org.pac4j.vertx.Pac4jHelper this class has methods to send messages to the busmod based on the
HttpServerRequest
object - org.pac4j.vertx.AuthHttpServerRequest this class wraps a standard
HttpServerRequest
object and allows to attach the current User Profile. This is useful in the handlers behind theRequiresAuthenticationHandler
in order to retrieve the User Profile - org.pac4j.vertx.handlers.HandlerHelper this class allows to detect a form POST request and forward to the next handler when the data are available. It is recommended to add this handler at the root of your server if you target to use form based authentication or SAML
- org.pac4j.vertx.handlers.RequiresAuthenticationHandler this class encapsulates another handler. It forwards the request to the handler if the user is already authenticated or redirects the user to the authentication provider otherwise
- org.pac4j.vertx.handlers.CallbackHandler this class finishes the authentication process if stateful, by validating the authentication information (e.g. a form with username and password) and storing the user profile in session
- org.pac4j.vertx.handlers.LogoutHandler this class removes the user profile from the session
The last three classes inherit from the org.pac4j.vertx.handlers.SessionAwareHandler
which uses a modified version of the session-manager helper from campudus.
Start the required modules and verticles:
public class Pac4jDemo extends Verticle {
@Override
public void start() {
// deploy session manager
container.deployModule("com.campudus~session-manager~2.0.1-final",
container.config().getObject("sessionManager"));
// deploy pac4j manager
container.deployModule("org.pac4j~vertx-pac4j-module~1.1.0-SNAPSHOT", container.config()
.getObject("pac4jManager"));
// deploy main verticle
container.deployVerticle("org.pac4j.vertx.DemoServerVerticle");
}}
Define the application verticle:
public class DemoServerVerticle extends Verticle {
@Override
public void start() {
// build session and pac4j helpers
SessionHelper sessionHelper = new SessionHelper(vertx);
Pac4jHelper pac4jHelper = new Pac4jHelper(vertx);
RouteMatcher rm = new RouteMatcher();
// the route '/facebook/index.html' requires an authentication and facebook will be used
rm.get("/facebook/index.html", new RequiresAuthenticationHandler("FacebookClient", new Handler(),
pac4jHelper, sessionHelper));
// register the callback handler
Handler<HttpServerRequest> callback = new CallbackHandler(pac4jHelper, sessionHelper);
rm.get("/callback", callback);
rm.post("/callback", callback);
// index page
rm.get("/", new Handler());
vertx.createHttpServer().requestHandler(HandlerHelper.addFormParsing(rm)).listen(8080, "localhost");
}}
Start the required modules and verticles:
public class Pac4jDemo extends Verticle {
@Override
public void start() {
// deploy pac4j manager
container.deployModule("org.pac4j~vertx-pac4j-module~1.1.0-SNAPSHOT", container.config()
.getObject("pac4jManager"));
// deploy main verticle
container.deployVerticle("org.pac4j.vertx.DemoRestServerVerticle");
}}
Define the application verticle:
public class DemoRestServerVerticle extends Verticle {
@Override
public void start() {
Pac4jHelper pac4jHelper = new Pac4jHelper(vertx);
RouteMatcher rm = new RouteMatcher();
rm.get("/", new RequiresAuthenticationHandler("BasicAuthClient", new DemoHandlers.AuthenticatedJsonHandler(),
pac4jHelper, true));
vertx.createHttpServer().requestHandler(rm).listen(8080, "localhost");
}
}