Customizations: (v4.4)
pac4j comes with a huge set of components for various needs, so before any customization, you should carefully read the Clients, Authenticators and Authorizers pages to check what is already provided.
1) Customizing the authentication/authorization components:
Be sure to clearly understand what the roles of the different components are:
- a
Client
is a whole login process: it is indirect for UI (IndirectClient
) and direct for web services (DirectClient
). It redirects to the identity provider (indirect client only), extracts the user credentials, validates the user credentials and creates a user profile for the authenticated user - a
RedirectionActionBuilder
redirects the user to the identity provider for login (indirect clients) - a
CredentialsExtractor
extracts the user credentials from the HTTP request (indirect and direct clients) - an
Authenticator
validates the user credentials (indirect and direct clients) - a
ProfileCreator
creates a user profile for the authenticated user (indirect and direct clients) - an
Authorizer
allows access based on the user profiles or on the web context - a
Matcher
defines if the security must apply on the web context - an
AuthorizationGenerator
generates the appropriate roles and permissions for a given user profile.
Overriding or creating new components should be straightforward.
Nonetheless, building a Client
requires extra efforts. Notice that:
-
you really need to understand what kind of authentication mechanism you want to support: is it for UI (credentials are provided only once and authentication almost always occurs at an external identity provider) or for web services (credentials are passed for every request)
-
all clients should implement the
IndirectClient
orDirectClient
base class and define the appropriateRedirectionActionBuilder
,CredentialsExtractor
,Authenticator
andProfileCreator
(and optionalLogoutActionBuilder
) -
it may be required to create a new
Credentials
type (if it is not a simple string designed by theTokenCredentials
or a username/password designed by theUsernamePasswordCredentials
). These new credentials may inherit from the base credentials of the supported protocol (likeOAuthCredentials
) -
it is generally a good practice to create a new profile for a new client (whether this profile will have or not specific data) to be able to distinguish between all the user profiles. The new user profile should certainly inherit from the base profile of the protocol support, like
OAuth20Profile
. At least, it must inherit fromCommonProfile
. The data returned by the identity provider may need to be converted (a single string into a Java enumeration for example) and for that, converters (classes extendingAttributeConverter
) are necessary. Both the converters and the returned user profile class must be defined in aProfileDefinition
.
2) Changing the core flow:
Overriding or creating new components allows you to implement new behaviour inside the boundaries of the defined logics of the regular pac4j web components.
Though, in some cases, it may not be enough. So you may decide to break the flow and change the provided behaviour by requesting some extra actions.
And this can be done by throwing an HttpAction
(like any exception) as most components allow that.
Example:
public class ExampleAuthorizer implements Authorizer<CommonProfile> {
@Override
public boolean isAuthorized(WebContext context, List<CommonProfile> profiles) throws HttpAction {
if ("specificValue".equals(context.getRequestHeader("specificHeader")))
{
throw HttpAction.redirect("force redirection", context, "/message.html");
}
return true;
}
}
3) Customizing the web integration
pac4j implementations heavily rely on the WebContext
and SessionStore
to deal with the HTTP request, response and session. The default implementations of theses component may be override or replaced.
As well as the default ProfileManager
(used to save/restore the profile) or GuavaStore
(to save data in cache).
In all cases, there is nothing better than taking a look at the existing components as examples. Don’t hesitate to ask any question on the pac4j-dev mailing list.