Skip to content

Security configuration

LELEU Jérôme edited this page Sep 9, 2020 · 1 revision

The configuration (org.pac4j.core.config.Config) contains all the clients and authorizers required by the application to handle security.

GoogleOidcClient oidcClient = new GoogleOidcClient();
oidcClient.setClientID("id");
oidcClient.setSecret("secret");
oidcClient.addCustomParam("prompt", "consent");

SAML2ClientConfiguration cfg = new SAML2ClientConfiguration("resource:samlKeystore.jks",
    "pac4j-demo-passwd", "pac4j-demo-passwd", "resource:testshib-providers.xml");
cfg.setMaximumAuthenticationLifetime(3600);
cfg.setServiceProviderEntityId("urn:mace:saml:pac4j.org");
cfg.setServiceProviderMetadataPath("sp-metadata.xml");
SAML2Client saml2Client = new SAML2Client(cfg);

FacebookClient facebookClient = new FacebookClient("fbId", "fbSecret");
TwitterClient twitterClient = new TwitterClient("twId", "twSecret");

FormClient formClient = new FormClient("http://localhost:8080/loginForm.jsp",
    new SimpleTestUsernamePasswordAuthenticator());
IndirectBasicAuthClient basicAuthClient = new IndirectBasicAuthClient(
    new SimpleTestUsernamePasswordAuthenticator());

CasClient casClient = new CasClient("http://mycasserver/login");

ParameterClient parameterClient = new ParameterClient("token", new JwtAuthenticator("salt"));

Config config = new Config("/callback", oidcClient, saml2Client, facebookClient,
	                  twitterClient, formClient, basicAuthClient, casClient, parameterClient);
config.getClients().setUrlResolver(new JaxRsUrlResolver());
config.getClients().setAjaxRequestResolver(new JaxRsAjaxRequestResolver());

config.addAuthorizer("admin", new RequireAnyRoleAuthorizer("ROLE_ADMIN"));
config.addAuthorizer("custom", new CustomAuthorizer());
}

Customization

  1. RECOMMENDED the JaxRsUrlResolver as the default callback url resolver, it will ensure that in practice, the callback url passed to external authentication system corresponds to the real URL of the callback endpoint

  2. RECOMMENDED the JaxRsAjaxRequestResolver as the default callback url resolver, it will ensure that the endpoints won't redirect to the login page but answer 401 in case of authentication error

  3. a specific SessionStore using the setSessionStore(sessionStore) method (by default, with JaxRsContextFactoryProvider, session handling is not supported; with ServletJaxRsContextFactoryProvider, it uses the ServletJaxRsSessionStore which relies on the underlying Servlet Container HTTP session; and with GrizzlyJaxRsContextFactoryProvider, it uses the GrizzlySessionStore which relies on the underlying HTTP session managed by Grizzly).

  4. specific matchers via the addMatcher(name, Matcher) method.

JAX-RS Configuration

The configuration is then passed to the various Providers and Features presented previously.

For a bare JAX-RS implementation without session management and annotation-support (here with Jersey, to be adapted):

resourceConfig
    .register(new JaxRsContextFactoryProvider(config))
    .register(new Pac4JSecurityFeature(config));

For a Jersey-based and Servlet-based (e.g., Jetty or Grizzly Servlet) environment with session management, annotation support and method parameters injection:

resourceConfig
    .register(ServletJaxRsContextFactoryProvider.class)
    .register(new Pac4JSecurityFeature(config))
    .register(new Pac4JValueFactoryProvider.Binder());

For a Jersey-based and Grizzly-based environment without Servlet but session management and annotation support and method parameters injection:

resourceConfig
    .register(new GrizzlyJaxRsContextFactoryProvider(config))
    .register(new Pac4JSecurityFeature(config))
    .register(new Pac4JValueFactoryProvider.Binder());

For a Resteasy-based and Servlet-based (e.g., Undertow) environment with session management and annotation support:

    public class MyApp extends Application {
        ...

        @Override
        public Set<Object> getSingletons() {
            Config config = getConfig();
            Set<Object> singletons = new HashSet<>();
            singletons.add(new Pac4JSecurityFeature(config));
            return singletons;
        }

        @Override
        public Set<Class<?>> getClasses() {
            Set<Class<?>> classes = new HashSet<>();
            classes.add(ServletJaxRsContextFactoryProvider.class);
            classes.add(Pac4JProfileInjectorFactory.class);
            return classes;
        }
    }

For RestEasy, you need to include resteasy-cdi support to your project to ensure that dependencies are injected at runtime. Refer to the tests in resteasy-pac4j module.

Note that a default value for the clients parameter of the @Pac4JSecurity annotation can be passed to the constructor of Pac4JSecurityFeature.

JAX-RS Autoscanning

When autoscanning is enabled, dropping the jax-rs-pac4j jar in the classpath won't have any effect. The developper always need to make some choices on which provider must be used depending on its environment.

A good practice in this context would be to define a JAX-RS @Provider to setup it like so:

@Provider
public class Pac4JFeature implements Feature {

    @Override
    public boolean configure(FeatureContext context) {
        context
            .register(new JaxRsConfigProvider(config))
            .register(new Pac4JSecurityFeature())
            .register(new Pac4JValueFactoryProvider.Binder()) // only with Jersey
            .register(new Pac4JProfileInjectorFactory()) // only with Resteasy
            .register(new ServletJaxRsContextFactoryProvider());

        return true;
    }
}

The content of this file would vary depending on your environment as explained in the previous section.

Clone this wiki locally