Build Status Maven Central

dropwizard-pac4j

A Dropwizard bundle for securing REST endpoints using pac4j.

Usage

dropwizard-pac4j provides two components which must be integrated into applications:

Dependencies (dropwizard-pac4j + pac4j-* libraries)

You need to add a dependency on:

All released artifacts are available in the Maven central repository.

Installing the bundle

Add the bundle within the application class' initialize method, just like any other bundle:

public class MySecureApplication extends Application<MySecureConfiguration> {
    final Pac4jBundle<MySecureConfiguration> bundle = new Pac4jBundle<MySecureConfiguration>() {
        @Override
        public Pac4jFactory getPac4jFactory(MySecureConfiguration configuration) {
            return configuration.getPac4jFactory();
        }
    };

    @Override
    public void initialize(Bootstrap<TestConfiguration> bootstrap) {
        bootstrap.addBundle(bundle);
    }

    ...

It can be useful to store the bundle in its own field in order to be able to access pac4j configuration as shown at the end of the next section.

Configuring the bundle

Update the application's configuration class to expose accessor methods for Pac4jFactory:

public class MySecureConfiguration extends Configuration {
    @NotNull
    Pac4jFactory pac4jFactory = new Pac4jFactory();

    @JsonProperty("pac4j")
    public Pac4jFactory getPac4jFactory() {
        return pac4jFactory;
    }

    @JsonProperty("pac4j")
    public void setPac4jFactory(Pac4jFactory pac4jFactory) {
        this.pac4jFactory = pac4jFactory;
    }
}

Note that it is also possible to have pac4jFactory be nullable and in this case, pac4j won't be configured but pac4j's type will be readable in the configuration. If the latter is not desired, do not use this bundle!

Add a pac4j section to a Dropwizard application's configuration file:

pac4j:
  # those protect the whole application at Jersey level
  globalFilters:
    - matchers: excludeUserSession
      authorizers: isAuthenticated
  servlet:
    security:
      - ...
    callback:
      - ...
    logout:
      - ...
  matchers:
    # this let the /user/session url be handled by the annotations
    excludeUserSession:
      class: org.pac4j.core.matching.PathMatcher
      excludePath: ^/user/session$
  callbackUrl: /user/session
  defaultClient: DirectBasicAuthClient
  clients:
    - org.pac4j.http.client.direct.DirectBasicAuthClient:
        authenticator:
          class: org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator

To specify instances of Client, Authenticator, PasswordEncoder, CredentialsExtractor, ProfileCreator, AuthorizationGenerator, Authorizer, Matcher, CallbackUrlResolver, HttpActionAdapter and RedirectActionBuilder, it only necessary to refer to their class name using the class key as above and the other properties are set on the instantiated object.

URLs Relativity

Note that all urls used within Jersey filters are relative to the dropwizard applicationContext suffixed by the dropwizard roothPath while the urls used within Servlet filters are only relative to the dropwizard applicationContext.

For Jersey, this also includes callbackUrls, enforced by JaxRsCallbackUrlResolver, which is the defaultCallbackUrlResolver in the config if not overridden.

Advanced Configuration

For more complex setup of pac4j configuration, the Config can be retrieved from the Pac4jBundle object stored in your Application:

public class MySecureApplication extends Application<MySecureConfiguration> {

    final Pac4jBundle<MySecureConfiguration> bundle = ...;

    @Override
    public void run(MySecureConfiguration config, Environment env) throws Exception {
        Config conf = bundle.getConfig()

        DirectBasicAuthClient c = conf.getClients().findClient(DirectBasicAuthClient.class);
        c.setCredentialsExtractor(...);

        env.jersey().register(new DogsResource());
    }
}

Securing REST endpoints

From here, jax-rs-pac4j takes over with its annotations. See pac4j documentation on how to implement Clients, Authorizers, Matchers and all the other points of extension.

Usage with Dropwizard's ResourceTestRule

When using ResourceTestRule, it usually make sense to mock the profile that is injected for @Pac4jProfile annotations by using one of the alternative Pac4JValueFactoryProvider binders:

@Rule
public final ResourceTestRule resources = ResourceTestRule.builder()
      .addProvide(MyResource.class)
      .addProvider(new Pac4JValueFactoryProvider.Binder(new CockpitProfile("my-mock-user-id")))
      .build();

Release notes

See the release notes. Learn more by browsing the dropwizard-pac4j Javadoc and the pac4j Javadoc.

Need help?

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

Development

The version 3.0.0-SNAPSHOT is under development.

Maven artifacts are built via Travis and available in the Sonatype snapshots repository. This repository must be added in the Maven settings.xml or pom.xml files:

<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>