Skip to content

Multi protocols (OAuth, OpenID, CAS, SAML, HTTP, GAE) security library for J2E

License

Notifications You must be signed in to change notification settings

jgribonvald/j2e-pac4j

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

86 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

What is the j2e-pac4j library ? Build Status

The j2e-pac4j library is a J2E multi-protocols authentication and authorization client.

It supports these 7 authentication mechanisms on client side (stateful, redirection back and forth to an identity provider for login):

  1. OAuth (1.0 & 2.0)
  2. CAS (1.0, 2.0, SAML, logout & proxy)
  3. HTTP (form & basic auth authentications)
  4. OpenID
  5. SAML (2.0)
  6. GAE UserService
  7. OpenID Connect (1.0)

as well as stateless REST calls (direct access to the web application with credentials).

It's available under the Apache 2 license and based on the pac4j library.

Providers supported

ProviderProtocolMaven dependencyClient classProfile class
CAS serverCASpac4j-casCasClient & CasProxyReceptorCasProfile
CAS server using OAuth WrapperOAuth 2.0pac4j-oauthCasOAuthWrapperClientCasOAuthWrapperProfile
DropBoxOAuth 1.0pac4j-oauthDropBoxClientDropBoxProfile
FacebookOAuth 2.0pac4j-oauthFacebookClientFacebookProfile
GitHubOAuth 2.0pac4j-oauthGitHubClientGitHubProfile
GoogleOAuth 2.0pac4j-oauthGoogle2ClientGoogle2Profile
LinkedInOAuth 1.0 & 2.0pac4j-oauthLinkedInClient & LinkedIn2ClientLinkedInProfile & LinkedIn2Profile
TwitterOAuth 1.0pac4j-oauthTwitterClientTwitterProfile
Windows LiveOAuth 2.0pac4j-oauthWindowsLiveClientWindowsLiveProfile
WordPressOAuth 2.0pac4j-oauthWordPressClientWordPressProfile
YahooOAuth 1.0pac4j-oauthYahooClientYahooProfile
PayPalOAuth 2.0pac4j-oauthPayPalClientPayPalProfile
VkOAuth 2.0pac4j-oauthVkClientVkProfile
FoursquareOAuth 2.0pac4j-oauthFoursquareClientFoursquareProfile
BitbucketOAuth 1.0pac4j-oauthBitbucketClientBitbucketProfile
ORCiDOAuth 2.0pac4j-oauthOrcidClientOrcidProfile
StravaOAuth 2.0pac4j-oauthStravaClientStravaProfile
Web sites with basic auth authenticationHTTPpac4j-httpBasicAuthClientHttpProfile
Web sites with form authenticationHTTPpac4j-httpFormClientHttpProfile
Google - DeprecatedOpenIDpac4j-openidGoogleOpenIdClientGoogleOpenIdProfile
YahooOpenIDpac4j-openidYahooOpenIdClientYahooOpenIdProfile
SAML Identity ProviderSAML 2.0pac4j-samlSaml2ClientSaml2Profile
Google App Engine User ServiceGae User Service Mechanismpac4j-gaeGaeUserServiceClientGaeUserServiceProfile
OpenID Connect ProviderOpenID Connect 1.0pac4j-oidcOidcClientOidcProfile

Technical description

This library has only 5 classes :

  1. the ClientConfiguration class gathers all the clients configuration
  2. the ClientsConfigFilter is an abstract J2E filter in charge of loading clients configuration
  3. the RequiresAuthenticationFilter is a J2E filter to protect urls and requires authentication for them. The filter has a stateful or stateless mode.
  4. the CallbackFilter is a J2E filter to handle the callback of the provider after authentication to finish the authentication process
  5. the UserUtils is an helper class to know if the user is authenticated, his profile and log out him.

and is based on the pac4j-* libraries.

Learn more by browsing the j2e-pac4j Javadoc and the pac4j Javadoc.

Sequence diagram of the RequiresAuthenticationFilter

Sequence diagram of the CallbackFilter

How to use it ?

Add the required dependencies

If you want to use a specific client support, you need to add the appropriate Maven dependency in the pom.xml file :

  • for OAuth support, the pac4j-oauth dependency is required
  • for CAS support, the pac4j-cas dependency is required
  • for HTTP support, the pac4j-http dependency is required
  • for OpenID support, the pac4j-openid dependency is required
  • for SAML support, the pac4j-saml dependency is required
  • for Google App Engine support, the pac4j-gae dependency is required
  • for OpenID Connect support, the pac4j-oidc dependency is required.

For example, to add OAuth support, add the following XML snippet :

<dependency>
  <groupId>org.pac4j</groupId>
  <artifactId>pac4j-oauth</artifactId>
  <version>1.7.0</version>
</dependency>

As these snapshot dependencies are only available in the Sonatype snapshots repository, the appropriate repository must be added in the pom.xml file also :

<repositories>
  <repository>
    <id>sonatype-nexus-snapshots</id>
    <name>Sonatype Nexus Snapshots</name>
    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    <releases>
      <enabled>false</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </repository>
</repositories>

Define the clients

All the clients used to communicate with various providers (Facebook, Twitter, a CAS server...) must be defined in a specific class implementing the org.pac4j.core.client.ClientsFactory interface. For example :

public class MyClientsFactory implements ClientsFactory {
  
  @Override
  public Clients build(final Object env) {
    final FacebookClient facebookClient = new FacebookClient("fbkey", "fbsecret");
    final TwitterClient twitterClient = new TwitterClient("twkey", "twsecret");
    // HTTP
    final FormClient formClient = new FormClient("https://localhost:8080/theForm.jsp", new SimpleTestUsernamePasswordAuthenticator());
    final BasicAuthClient basicAuthClient = new BasicAuthClient(new SimpleTestUsernamePasswordAuthenticator());        
    // CAS
    final CasClient casClient = new CasClient();
    casClient.setCasLoginUrl("https://localhost:8888/cas/login");        
    // OpenID
    final GoogleOpenIdClient googleOpenIdClient = new GoogleOpenIdClient();
    final Clients clients = new Clients("https://localhost:8080/callback", facebookClient, twitterClient, formClient, basicAuthClient, casClient, googleOpenIdClient);
    return clients;
  }
}

Choose between stateful or stateless mode

Pac4j was initially designed to provide authentication flows for web applications. This means it relies on a session concept and on HTTP redirections: this is the stateful mode and it is activated by default. In this mode, you need to configure what we call the callback filter in order to finish the authentication process.

Since j2e-pac4j version 1.1.0, we support now a stateless mode. This can be typically used to protect REST WS where a single HTTP call must be enough to retrieve the resource. A good example of stateless authentication is the basic-auth method where the browser includes in all requests the HTTP Authorization header with the login and password base64 encoded.

I. stateful mode

Define the "callback filter"

To handle callback from providers, you need to define the appropriate J2E filter and its mapping :

<filter>
  <filter-name>CallbackFilter</filter-name>
  <filter-class>org.pac4j.j2e.filter.CallbackFilter</filter-class>
  <init-param>
  	<param-name>clientsFactory</param-name>
  	<param-value>org.leleuj.config.MyClientsFactory</param-value>
  </init-param>
  <init-param>
  	<param-name>defaultUrl</param-name>
  	<param-value>/</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CallbackFilter</filter-name>
  <url-pattern>/callback</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Protect the urls

You can protect your urls and force the user to be authenticated by a client by using the appropriate filter and mapping. Key parameters are all the clients and the specific client (clientName) used by this filter.
For example, for Facebook :

<filter>
  <filter-name>FacebookFilter</filter-name>
  <filter-class>org.pac4j.j2e.filter.RequiresAuthenticationFilter</filter-class>
  <init-param>
   	<param-name>clientsFactory</param-name>
   	<param-value>org.leleuj.config.MyClientsFactory</param-value>
  </init-param>
  <init-param>
   	<param-name>clientName</param-name>
   	<param-value>FacebookClient</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>FacebookFilter</filter-name>
  <url-pattern>/facebook/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Get redirection urls

You can also explicitely compute a redirection url to a provider for authentication by using the getRedirectionUrl method and the ClientsConfiguration class. For example with Facebook :

<%
  WebContext context = new J2EContext(request, response);
  Clients client = ClientsConfiguration.getClients();
  FacebookClient fbClient = (FacebookClient) client.findClient("FacebookClient");
  String redirectionUrl = Client.getRedirectionUrl(context, false, false);
%>

Get the user profile

After successful authentication, you can test if the user is authenticated using UserUtils.isAuthenticated() or get the user profile using UserUtils.getUserProfile().

The profile returned is a CommonProfile, from which you can retrieve the most common properties that all profiles share. But you can also cast the user profile to the appropriate profile according to the provider used for authentication. For example, after a Facebook authentication :

// facebook profile
FacebookProfile facebookProfile = (FacebookProfile) commonProfile;

Or for all the OAuth 1.0/2.0 profiles, to get the access token :

OAuth10Profile oauthProfile = (OAuth10Profile) commonProfile
String accessToken = oauthProfile.getAccessToken();
// or
String accessToken = facebookProfile.getAccessToken();

II. Stateless mode

In this mode, you need just to protect your resources with the ClientAuthenticationFilter filter and configure the stateless parameter to true.

<filter>
  <filter-name>StatelessBasicAuthFilter</filter-name>
  <filter-class>org.pac4j.j2e.filter.RequiresAuthenticationFilter</filter-class>
  <init-param>
   	<param-name>clientsFactory</param-name>
   	<param-value>org.leleuj.config.MyClientsFactory</param-value>
  </init-param>
  <init-param>
   	<param-name>clientName</param-name>
   	<param-value>BasicAuthClient</param-value>
  </init-param>
  <init-param>
   	<param-name>stateless</param-name>
   	<param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>StatelessBasicAuthFilter</filter-name>
  <url-pattern>/rest-basic-auth/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Get the user profile

After successful authentication, you can test if the user is authenticated using UserUtils.isAuthenticated() or get the user profile using UserUtils.getUserProfile().

Handling authorization

When you protect a resource with the ClientAuthenticationFilter, you can also restrict its access to predefined roles depending on the user profiles. You can use two parameters for that:

  1. requireAnyRole
  2. requireAllRoles

For example if you want to restrict the access to the user having the role ROLE_ADMIN:

<filter>
  <filter-name>StatelessBasicAuthFilter</filter-name>
  <filter-class>org.pac4j.j2e.filter.RequiresAuthenticationFilter</filter-class>
  <init-param>
   	<param-name>clientsFactory</param-name>
   	<param-value>org.leleuj.config.MyClientsFactory</param-value>
  </init-param>
  <init-param>
   	<param-name>clientName</param-name>
   	<param-value>BasicAuthClient</param-value>
  </init-param>
  <init-param>
   	<param-name>stateless</param-name>
   	<param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>requireAnyRole</param-name>
    <param-value>ROLE_ADMIN</param-value>
  </init-param>
</filter>

Of course you need also to configure a correct AuthorizationGenerator (see authorizations).

Demo

A demo with Facebook, Twitter, CAS, form authentication and basic auth authentication providers is available with j2e-pac4j-demo.

Versions

The current version 1.1.1-SNAPSHOT is under development. It's available on the Sonatype snapshots repository as a Maven dependency :

The last released version is the 1.1.0 :

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>j2e-pac4j</artifactId>
    <version>1.1.0</version>
</dependency>

See the release notes.

Contact

If you have any question, please use the following mailing lists :

About

Multi protocols (OAuth, OpenID, CAS, SAML, HTTP, GAE) security library for J2E

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 98.6%
  • Shell 1.4%