/undertow-pac4j

Multi protocols (CAS, OAuth, OpenID, SAML, HTTP...) client for Undertow

Primary LanguageJava

What is the undertow-pac4j library ? Build Status

The undertow-pac4j library is an authentication multi-protocols client for JBoss Undertow.

It supports these 6 authentication mechanisms on client side :

  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

It's available under the Apache 2 license and based on my 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
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

Technical description

This library consists of the following main classes :

  1. the ClientAuthenticationMechanism is a new Undertow authentication mechanism delegating to the pac4j clients
  2. the Config is a configuration holder; important attributes are the Undertow SessionManager and SessionConfig
  3. the HandlerHelper contains utility methods for enhancing Undertow handlers with additional functionality like security, form data management and session
  4. the CallbackHandler is an Undertow handler to handle the callback of the provider after authentication to finish the authentication process
  5. the LogoutHandler is an Undertow handler to handle the logout of the user

and is based on the pac4j-* libraries.

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

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 example, to add OAuth support, add the following XML snippet :

<dependency>
  <groupId>org.pac4j</groupId>
  <artifactId>pac4j-oauth</artifactId>
  <version>1.6.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 and the config object

All the clients used to communicate with various providers (Facebook, Twitter, a CAS server...) must be defined in your Undertow Server. For example :

public class DemoServer {
  
  public Clients buildClients() {
    final FacebookClient facebookClient = new FacebookClient("fbkey", "fbsecret");
    final TwitterClient twitterClient = new TwitterClient("twkey", "twsecret");
    // HTTP
    final FormClient formClient = new FormClient("http://localhost:8080/theForm.jsp", new SimpleTestUsernamePasswordAuthenticator());
    final BasicAuthClient basicAuthClient = new BasicAuthClient(new SimpleTestUsernamePasswordAuthenticator());        
    // CAS
    final CasClient casClient = new CasClient();
    casClient.setCasLoginUrl("http://localhost:8888/cas/login");        
    // OpenID
    final GoogleOpenIdClient googleOpenIdClient = new GoogleOpenIdClient();
    final Clients clients = new Clients("http://localhost:8080/callback", facebookClient, twitterClient, formClient, basicAuthClient, casClient, googleOpenIdClient);
    return clients;
  }
  
  public static void main(final String[] args) {

    Config config = new Config();
    config.setClients(buildClients());
    
  }
}

Define the "callback filter"

To handle callback from providers, you need to define the appropriate handler :

public static void main(final String[] args) {

    Config config = new Config();
    config.setClients(buildClients());
    PathHandler path = new PathHandler();
    path.addExactPath("/callback", CallbackHandler.build(config));
    
  }

Protect the urls

You can protect your urls and force the user to be authenticated by a client by using the requireAuthentication handler helper.
For example, for Facebook if you want to protect the facebookHandler :

public static void main(final String[] args) {

    Config config = new Config();
    config.setClients(buildClients());
    PathHandler path = new PathHandler();
    path.addExactPath("/callback", CallbackHandler.build(config));
    path.addExactPath("/facebook/index.html",
            HandlerHelper.requireAuthentication(facebookHandler, config, "FacebookClient", false));
    
}

Add session capability

Finally you can finalize the configuration by adding session management and start the server:

public static void main(final String[] args) {

    Config config = new Config();
    config.setClients(buildClients());
    PathHandler path = new PathHandler();
    path.addExactPath("/callback", CallbackHandler.build(config));
    path.addExactPath("/facebook/index.html",
            HandlerHelper.requireAuthentication(facebookHandler, config, "FacebookClient", false));
    
    Undertow server = Undertow.builder().addListener(8080, "localhost")
            .setHandler(HandlerHelper.addSession(path, config)).build();
    server.start();
    
}

Get redirection urls

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

StorageHelper.createSession(exchange);
WebContext context = new UndertowWebContext(exchange);
Clients client = config.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 StorageHelper.getProfile().

This method returns a wrapper containing an undertow account and a pac4j profile. This profile 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();

Demo

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

Versions

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

Contact

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