package org.pac4j.dropwizard; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import javax.validation.constraints.NotNull; import org.pac4j.config.client.PropertiesConfigFactory; import org.pac4j.core.authorization.authorizer.Authorizer; import org.pac4j.core.authorization.generator.AuthorizationGenerator; import org.pac4j.core.client.Client; import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; import org.pac4j.core.config.ConfigBuilder; import org.pac4j.core.context.WebContext; import org.pac4j.core.engine.CallbackLogic; import org.pac4j.core.engine.LogoutLogic; import org.pac4j.core.engine.SecurityLogic; import org.pac4j.core.http.adapter.HttpActionAdapter; import org.pac4j.core.http.ajax.AjaxRequestResolver; import org.pac4j.core.http.url.UrlResolver; import org.pac4j.core.matching.Matcher; import org.pac4j.core.profile.ProfileManager; import org.pac4j.jax.rs.pac4j.JaxRsAjaxRequestResolver; import org.pac4j.jax.rs.pac4j.JaxRsUrlResolver; import com.fasterxml.jackson.annotation.JsonProperty; /** * Dropwizard configuration factory to configure pac4j's {@link Config}, * {@link Clients}, global JAX-RS * {@link org.pac4j.jax.rs.filters.SecurityFilter}s as well as Servlet's * {@link org.pac4j.j2e.filter.SecurityFilter}s, * {@link org.pac4j.j2e.filter.CallbackFilter}s and * {@link org.pac4j.j2e.filter.LogoutFilter}s. * * @see Pac4jConfiguration * @see org.pac4j.core.config.Config * @see org.pac4j.core.client.Clients * @author Evan Meagher * @author Victor Noel - Linagora * @since 1.0.0 */ public class Pac4jFactory { @NotNull private List<JaxRsSecurityFilterConfiguration> globalFilters = new ArrayList<>(); @NotNull private ServletConfiguration servlet = new ServletConfiguration(); private SecurityLogic securityLogic; private CallbackLogic callbackLogic; private LogoutLogic logoutLogic; private String callbackUrl; private AjaxRequestResolver ajaxRequestResolver = new JaxRsAjaxRequestResolver(); private UrlResolver urlResolver = new JaxRsUrlResolver(); private HttpActionAdapter httpActionAdapter; private Function<WebContext, ProfileManager> profileManagerFactory; private boolean sessionEnabled = true; @NotNull private List<AuthorizationGenerator> authorizationGenerators = new ArrayList<>(); @NotNull private Map<String, Matcher> matchers = new HashMap<>(); @NotNull private List<Client> clients = new ArrayList<>(); private String defaultSecurityClients = null; @NotNull private Map<String, Authorizer> authorizers = new HashMap<>(); @NotNull private Map<String, String> configProperties = new HashMap<>(); private String configClass; @NotNull private Map<String, String> clientsProperties = new HashMap<>(); @JsonProperty public Map<String, String> getConfigProperties() { return configProperties; } @JsonProperty public void setConfigProperties(final Map<String, String> configProperties) { this.configProperties = configProperties; } @JsonProperty public String getConfigClass() { return configClass; } @JsonProperty public void setConfigClass(final String configClass) { this.configClass = configClass; } @JsonProperty public Map<String, String> getClientsProperties() { return clientsProperties; } @JsonProperty public void setClientsProperties(final Map<String, String> clientsProperties) { this.clientsProperties = clientsProperties; } @JsonProperty public List<JaxRsSecurityFilterConfiguration> getGlobalFilters() { return globalFilters; } @JsonProperty public void setGlobalFilters( List<JaxRsSecurityFilterConfiguration> filters) { this.globalFilters = filters; } /** * @since 1.1.0 * @return configuration for servlet filters */ @JsonProperty public ServletConfiguration getServlet() { return servlet; } /** * @since 1.1.0 * * @param servlet * configuration for servlet filters */ @JsonProperty public void setServlet(ServletConfiguration servlet) { this.servlet = servlet; } /** * @since 1.1.1 * * @param securityLogic * the {@link SecurityLogic} to use globally */ @JsonProperty public void setSecurityLogic(SecurityLogic securityLogic) { this.securityLogic = securityLogic; } @JsonProperty public SecurityLogic getSecurityLogic() { return securityLogic; } /** * @since 1.1.1 * * @param callbackLogic * the {@link CallbackLogic} to use globally */ @JsonProperty public void setCallbackLogic(CallbackLogic callbackLogic) { this.callbackLogic = callbackLogic; } @JsonProperty public CallbackLogic getCallbackLogic() { return callbackLogic; } /** * @since 1.1.1 * * @param logoutLogic * the {@link LogoutLogic} to use globally */ @JsonProperty public void setLogoutLogic(LogoutLogic logoutLogic) { this.logoutLogic = logoutLogic; } @JsonProperty public LogoutLogic getLogoutLogic() { return logoutLogic; } @JsonProperty public String getCallbackUrl() { return callbackUrl; } @JsonProperty public void setCallbackUrl(String callbackUrl) { this.callbackUrl = callbackUrl; } @JsonProperty public List<AuthorizationGenerator> getAuthorizationGenerators() { return authorizationGenerators; } @JsonProperty public void setAuthorizationGenerators( List<AuthorizationGenerator> authorizationGenerators) { this.authorizationGenerators = authorizationGenerators; } @JsonProperty public Map<String, Matcher> getMatchers() { return matchers; } @JsonProperty public void setMatchers(Map<String, Matcher> matchers) { this.matchers = matchers; } @JsonProperty public List<Client> getClients() { return clients; } @JsonProperty public void setClients(List<Client> clients) { this.clients = clients; } @JsonProperty public String getDefaultSecurityClients() { return defaultSecurityClients; } @JsonProperty public void setDefaultSecurityClients(String defaultSecurityClients) { this.defaultSecurityClients = defaultSecurityClients; } @JsonProperty public Map<String, Authorizer> getAuthorizers() { return authorizers; } @JsonProperty public void setAuthorizers(Map<String, Authorizer> authorizers) { this.authorizers = authorizers; } @JsonProperty public AjaxRequestResolver getAjaxRequestResolver() { return ajaxRequestResolver; } @JsonProperty public void setAjaxRequestResolver(AjaxRequestResolver ajaxRequestResolver) { this.ajaxRequestResolver = ajaxRequestResolver; } @JsonProperty public UrlResolver getUrlResolver() { return urlResolver; } @JsonProperty public void setUrlResolver(UrlResolver urlResolver) { this.urlResolver = urlResolver; } /** * @since 1.1.1 * @return an {@link HttpActionAdapter} */ @JsonProperty public HttpActionAdapter getHttpActionAdapter() { return httpActionAdapter; } @JsonProperty public void setHttpActionAdapter(HttpActionAdapter httpActionAdapter) { this.httpActionAdapter = httpActionAdapter; } @JsonProperty public Function<WebContext, ProfileManager> getProfileManagerFactory() { return profileManagerFactory; } /** * @since 2.0.0 * @param profileManagerFactory * a class implementing a function from context to profile * manager */ @JsonProperty public void setProfileManagerFactory( Function<WebContext, ProfileManager> profileManagerFactory) { this.profileManagerFactory = profileManagerFactory; } /** * @since 1.1.0 * @return <code>true</code> if the session management is to be enabled at * Jetty level */ @JsonProperty public boolean getSessionEnabled() { return sessionEnabled; } /** * @param sessionEnabled * if <code>true</code> session management will be enabled at the * Jetty level, if <code>false</code> it won't. * @since 1.1.0 */ @JsonProperty public void setSessionEnabled(boolean sessionEnabled) { this.sessionEnabled = sessionEnabled; } public Config build() { // either the whole Config is built from a ConfigFactory class, or we initialize a default Config final Config config; if (configClass != null && !configProperties.isEmpty()) { config = ConfigBuilder.build(configClass, configProperties); } else { config = new Config(); } Clients newClients = config.getClients(); if (newClients == null) { newClients = new Clients(); config.setClients(newClients); } if (newClients.getClients() == null) { newClients.setClients(new ArrayList<>()); } // we can take the clients built from the properties if (!clientsProperties.isEmpty()) { final PropertiesConfigFactory propertiesConfigFactory = new PropertiesConfigFactory(clientsProperties); final Config propertiesConfig = propertiesConfigFactory.build(); config.getClients().getClients().addAll(propertiesConfig.getClients().getClients()); } // and the clients directly defined in the YAML file if (!clients.isEmpty()) { newClients.getClients().addAll(clients); } if (callbackUrl != null) { newClients.setCallbackUrl(callbackUrl); } newClients.setAjaxRequestResolver(ajaxRequestResolver); newClients.setUrlResolver(urlResolver); if (!authorizationGenerators.isEmpty()) { newClients.getAuthorizationGenerators().addAll(authorizationGenerators); } if (defaultSecurityClients != null) { newClients.setDefaultSecurityClients(defaultSecurityClients); } if (securityLogic != null) { config.setSecurityLogic(securityLogic); } if (callbackLogic != null) { config.setCallbackLogic(callbackLogic); } if (logoutLogic != null) { config.setLogoutLogic(logoutLogic); } if (httpActionAdapter != null) { config.setHttpActionAdapter(httpActionAdapter); } if (!authorizers.isEmpty()) { config.getAuthorizers().putAll(authorizers); } if (!matchers.isEmpty()) { config.getMatchers().putAll(matchers); } if (profileManagerFactory != null) { config.setProfileManagerFactory(profileManagerFactory); } return config; } /** * @since 1.1.0 */ public static class ServletConfiguration { @NotNull private List<ServletSecurityFilterConfiguration> security = new ArrayList<>(); @NotNull private List<ServletCallbackFilterConfiguration> callback = new ArrayList<>(); @NotNull private List<ServletLogoutFilterConfiguration> logout = new ArrayList<>(); @JsonProperty public List<ServletSecurityFilterConfiguration> getSecurity() { return security; } @JsonProperty public List<ServletCallbackFilterConfiguration> getCallback() { return callback; } @JsonProperty public List<ServletLogoutFilterConfiguration> getLogout() { return logout; } @JsonProperty public void setSecurity( List<ServletSecurityFilterConfiguration> filters) { this.security = filters; } @JsonProperty public void setCallback( List<ServletCallbackFilterConfiguration> filters) { this.callback = filters; } @JsonProperty public void setLogout(List<ServletLogoutFilterConfiguration> filters) { this.logout = filters; } } /** * @since 1.0.0 * @see org.pac4j.jax.rs.filters.SecurityFilter */ public static class JaxRsSecurityFilterConfiguration extends SecurityFilterConfiguration { private Boolean skipResponse; @JsonProperty public Boolean getSkipResponse() { return skipResponse; } @JsonProperty public void setSkipResponse(Boolean skipResponse) { this.skipResponse = skipResponse; } } /** * @since 1.1.0 * @see org.pac4j.j2e.filter.SecurityFilter */ public static class ServletSecurityFilterConfiguration extends SecurityFilterConfiguration { @NotNull private String mapping = "/*"; @JsonProperty public String getMapping() { return mapping; } @JsonProperty public void setMapping(String mapping) { this.mapping = mapping; } } /** * @since 1.1.0 */ public abstract static class SecurityFilterConfiguration { private String clients; private String authorizers; private String matchers; private Boolean multiProfile; @JsonProperty public String getClients() { return clients; } @JsonProperty public String getAuthorizers() { return authorizers; } @JsonProperty public String getMatchers() { return matchers; } @JsonProperty public Boolean getMultiProfile() { return multiProfile; } @JsonProperty public void setClients(String clients) { this.clients = clients; } @JsonProperty public void setAuthorizers(String authorizers) { this.authorizers = authorizers; } @JsonProperty public void setMatchers(String matchers) { this.matchers = matchers; } @JsonProperty public void setMultiProfile(Boolean multiProfile) { this.multiProfile = multiProfile; } } /** * @since 1.1.0 * @see org.pac4j.j2e.filter.CallbackFilter */ public static class ServletCallbackFilterConfiguration { @NotNull private String mapping; private String defaultUrl; private Boolean multiProfile; private Boolean renewSession; @JsonProperty public String getMapping() { return mapping; } @JsonProperty public String getDefaultUrl() { return defaultUrl; } @JsonProperty public Boolean getMultiProfile() { return multiProfile; } @JsonProperty public Boolean getRenewSession() { return renewSession; } @JsonProperty public void setMapping(String mapping) { this.mapping = mapping; } @JsonProperty public void setDefaultUrl(String defaultUrl) { this.defaultUrl = defaultUrl; } @JsonProperty public void setMultiProfile(Boolean multiProfile) { this.multiProfile = multiProfile; } @JsonProperty public void setRenewSession(Boolean renewSession) { this.renewSession = renewSession; } } /** * @since 1.1.0 * @see org.pac4j.j2e.filter.LogoutFilter */ public static class ServletLogoutFilterConfiguration { @NotNull private String mapping; private String defaultUrl; private String logoutUrlPattern; private Boolean localLogout; private Boolean destroySession; private Boolean centralLogout; @JsonProperty public String getMapping() { return mapping; } @JsonProperty public String getDefaultUrl() { return defaultUrl; } @JsonProperty public String getLogoutUrlPattern() { return logoutUrlPattern; } @JsonProperty public Boolean getLocalLogout() { return localLogout; } @JsonProperty public Boolean getDestroySession() { return destroySession; } @JsonProperty public Boolean getCentralLogout() { return centralLogout; } @JsonProperty public void setMapping(String mapping) { this.mapping = mapping; } @JsonProperty public void setDefaultUrl(String defaultUrl) { this.defaultUrl = defaultUrl; } @JsonProperty public void setLogoutUrlPattern(String logoutUrlPattern) { this.logoutUrlPattern = logoutUrlPattern; } @JsonProperty public void setLocalLogout(Boolean localLogout) { this.localLogout = localLogout; } @JsonProperty public void setDestroySession(Boolean destroySession) { this.destroySession = destroySession; } @JsonProperty public void setCentralLogout(Boolean centralLogout) { this.centralLogout = centralLogout; } } }