ContextRegistrator.java revision 2ae41f94c30465830758177491494f918a7a79bc
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * Copyright (c) 2011-2012 ForgeRock AS. All rights reserved.
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * The contents of this file are subject to the terms
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * of the Common Development and Distribution License
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * (the License). You may not use this file except in
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * compliance with the License.
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * You can obtain a copy of the License at
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * See the License for the specific language governing
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * permission and limitations under the License.
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * When distributing Covered Code, include this CDDL
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * Header Notice in each file and include the License file
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * If applicable, add the following below the CDDL Header,
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * with the fields enclosed by brackets [] replaced by
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * your own identifying information:
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * "Portions Copyrighted [year] [name of copyright owner]"
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.apache.felix.scr.annotations.Activate;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.apache.felix.scr.annotations.Component;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.apache.felix.scr.annotations.ConfigurationPolicy;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.apache.felix.scr.annotations.Deactivate;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.apache.felix.scr.annotations.Reference;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.ops4j.pax.web.extender.whiteboard.ErrorPageMapping;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.ops4j.pax.web.extender.whiteboard.ExtenderConstants;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.ops4j.pax.web.extender.whiteboard.FilterMapping;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.ops4j.pax.web.extender.whiteboard.ListenerMapping;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.ops4j.pax.web.extender.whiteboard.ResourceMapping;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.ops4j.pax.web.extender.whiteboard.ServletMapping;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.ops4j.pax.web.extender.whiteboard.WelcomeFileMapping;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkimport org.osgi.service.component.ComponentContext;
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * Http context to share amongst OpenIDM servlets to allow for applying uniform
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * security handling
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * @author aegloff
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk@Component(name = "org.forgerock.openidm.http.context", immediate = true,
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenkpublic final class ContextRegistrator {
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk final static Logger logger = LoggerFactory.getLogger(ContextRegistrator.class);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk List<SecurityConfigurator> securityConfigurators = new ArrayList<SecurityConfigurator>();
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * Allow access for the fragments
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * @return bundle context if activated, null otherwise
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk public static BundleContext getBundleContext() {
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk protected void activate(ComponentContext context) throws Exception {
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk httpContext = httpService.createDefaultHttpContext();
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk Dictionary<String, Object> contextProps = new Hashtable<String, Object>();
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk contextProps.put("openidm.contextid", "shared");
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk contextProps.put(ExtenderConstants.PROPERTY_HTTP_CONTEXT_ID, OPENIDM);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk // TODO: Consider the HttpContextMapping it allows to configure the path
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk context.getBundleContext().registerService(HttpContext.class.getName(), httpContext,
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk logger.debug("Registered OpenIDM shared http context");
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk // Apply the pluggable security configurations on the httpContext
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk activateSecurityConfigurators(context, httpContext);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk protected void deactivate(ComponentContext context) {
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk deactivateSecurityConfigurators(context, httpContext);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * Loads and instantiates the pluggable Security Configurators
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * To allow for pluggability with fragments a simple convention is used to
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * find security configurator(s); 1. A properties file contains a property
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * security.configurator.class of a class in the bundle fragment that
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * implements SecurityConfigurator and has a no-arg constructor 2. The
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * properties file is name <prefix>securityconfigurator.properties and
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * placed somewhere in the bundle or attached fragments
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk context.getBundleContext().getBundle().findEntries("/",
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk while (entries != null && entries.hasMoreElements()) {
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk logger.trace("Handle properties file at {}", entry.getPath());
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk java.util.Properties props = new java.util.Properties();
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk logger.warn("Failed to load security extension properties file", ex);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk logger.warn("Failure during close of properties file.", cex);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk logger.trace("Loaded {}: {}", entry.getPath(), props);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk String clazzName = (String) props.get("security.configurator.class");
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk logger.debug("Initiating security configurator for class: {}", clazzName);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk SecurityConfigurator configurator = instantiateSecurityConfigurator(clazzName);
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * @param clazzName
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * name of SecurityConfigurator to load and instantiate
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * @return the security configurator instance if it was successfully
2a9ee4116a7df31d9482821f64c837315c8e2aa0jeff.schenk * instantiated, null if not. Logs any failures
return configurator;
null);
null);
null);
null);
return OPENIDM;