From f5f36545f32357c81ec4599a4f186e5e6ab507ae Mon Sep 17 00:00:00 2001 From: Paolo Antinori Date: Tue, 22 Mar 2016 10:00:43 +0100 Subject: [PATCH] KEYCLOAK-2805 - Support for JBoss Fuse 6.3 Upgrade of CXF, Jetty and Pax-Web required to rewrite part of the integration. --- adapters/oidc/osgi-adapter/pom.xml | 17 ++- .../osgi/ServletReregistrationService.java | 140 ++++++++++++++---- .../features/src/main/resources/features.xml | 14 +- examples/fuse/camel/pom.xml | 18 ++- examples/fuse/cxf-jaxrs/pom.xml | 7 +- .../resources/META-INF/cxf/bus-extensions.txt | 0 .../OSGI-INF/blueprint/blueprint.xml | 6 +- examples/fuse/cxf-jaxws/pom.xml | 5 +- .../features/src/main/resources/features.xml | 23 ++- examples/fuse/pom.xml | 7 +- pom.xml | 7 +- 11 files changed, 194 insertions(+), 50 deletions(-) create mode 100644 examples/fuse/cxf-jaxrs/src/main/resources/META-INF/cxf/bus-extensions.txt diff --git a/adapters/oidc/osgi-adapter/pom.xml b/adapters/oidc/osgi-adapter/pom.xml index f453ffd5f6..f4c708cc40 100755 --- a/adapters/oidc/osgi-adapter/pom.xml +++ b/adapters/oidc/osgi-adapter/pom.xml @@ -31,15 +31,19 @@ jar + + 3.1.5 8.1.17.v20150415 org.keycloak.adapters.osgi.* - org.ops4j.pax.web.*;version="[3.0,4)", + org.ops4j.pax.web.*;version="[3.0,5)", javax.servlet.*;version="[2.5,4)";resolution:=optional, org.eclipse.jetty.*;version="[8.1,10)";resolution:=optional, org.keycloak.*;version="${project.version}", + org.apache.cxf.transport.http;resolution:=optional;version="[3,4)", + org.apache.cxf.transport.servlet;resolution:=optional;version="[3,4)", *;resolution:=optional @@ -65,12 +69,23 @@ pax-web-runtime provided + + org.ops4j.pax.web + pax-web-api + provided + org.eclipse.jetty jetty-security ${jetty9.version} provided + + org.apache.cxf + cxf-rt-transports-http + ${cxf.version} + provided + diff --git a/adapters/oidc/osgi-adapter/src/main/java/org/keycloak/adapters/osgi/ServletReregistrationService.java b/adapters/oidc/osgi-adapter/src/main/java/org/keycloak/adapters/osgi/ServletReregistrationService.java index 3bff5a0530..1aace71011 100644 --- a/adapters/oidc/osgi-adapter/src/main/java/org/keycloak/adapters/osgi/ServletReregistrationService.java +++ b/adapters/oidc/osgi-adapter/src/main/java/org/keycloak/adapters/osgi/ServletReregistrationService.java @@ -18,15 +18,22 @@ package org.keycloak.adapters.osgi; import java.util.Arrays; +import java.util.Dictionary; +import java.util.Enumeration; import java.util.Hashtable; import java.util.List; +import java.util.Properties; import javax.servlet.Servlet; +import org.apache.cxf.transport.http.DestinationRegistry; +import org.apache.cxf.transport.servlet.CXFNonSpringServlet; import org.jboss.logging.Logger; import org.ops4j.pax.web.service.WebContainer; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.http.HttpContext; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; @@ -42,13 +49,15 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer; */ public class ServletReregistrationService { + private static final String CXF_SERVLET_PREFIX = "org.apache.cxf.servlet."; protected static final Logger log = Logger.getLogger(ServletReregistrationService.class); private static final List FILTERED_PROPERTIES = Arrays.asList("objectClass", "service.id"); private BundleContext bundleContext; - private ServiceReference servletReference; + private ServiceReference managedServiceReference; private ServiceTracker webContainerTracker; + private String alias; public BundleContext getBundleContext() { return bundleContext; @@ -58,24 +67,18 @@ public class ServletReregistrationService { this.bundleContext = bundleContext; } - public ServiceReference getServletReference() { - return servletReference; - } - - public void setServletReference(ServiceReference servletReference) { - this.servletReference = servletReference; - } - - protected ServiceTracker getWebContainerTracker() { - return webContainerTracker; - } public void start() { - if (servletReference == null) { - throw new IllegalStateException("No servlet reference provided"); + if ( managedServiceReference == null) { + return; + } + + Dictionary properties = obtainProperties(); + alias = (String)getProp(properties, CXF_SERVLET_PREFIX + "context", "/cxf"); + if(alias == null){ + alias = "/cxf"; } - final Servlet servlet = (Servlet) bundleContext.getService(servletReference); WebContainer externalWebContainer = findExternalWebContainer(); if (externalWebContainer == null) { return; @@ -83,18 +86,19 @@ public class ServletReregistrationService { // Unregister servlet from external container now try { - externalWebContainer.unregisterServlet(servlet); + externalWebContainer.unregister(alias); log.debug("Original servlet with alias " + getAlias() + " unregistered successfully from external web container."); } catch (IllegalStateException e) { log.warn("Can't unregister servlet due to: " + e.getMessage()); } + final Dictionary finalProperties = properties; ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() { @Override public Object addingService(ServiceReference webContainerServiceReference) { WebContainer ourWebContainer = (WebContainer) bundleContext.getService(webContainerServiceReference); - registerServlet(ourWebContainer, servlet); + registerServlet(ourWebContainer, finalProperties); log.debugv("Servlet with alias " + getAlias() + " registered to secured web container"); return ourWebContainer; } @@ -122,28 +126,82 @@ public class ServletReregistrationService { // Re-register servlet back to original context WebContainer externalWebContainer = findExternalWebContainer(); - Servlet servlet = (Servlet) bundleContext.getService(servletReference); - registerServlet(externalWebContainer, servlet); + registerServlet(externalWebContainer, obtainProperties()); log.debug("Servlet with alias " + getAlias() + " registered back to external web container"); } private String getAlias() { - return (String) servletReference.getProperty("alias"); + return alias; } - protected void registerServlet(WebContainer webContainer, Servlet servlet) { + /** + * Code comes from org.apache.cxf.transport.http.osgi.ServletExporter#updated(java.util.Dictionary) + * @param webContainer + * @param properties + */ + protected void registerServlet(WebContainer webContainer, Dictionary properties) { + HttpContext httpContext = webContainer.createDefaultHttpContext(); + + ServiceReference destinationServiceServiceReference = bundleContext.getServiceReference("org.apache.cxf.transport.http.DestinationRegistry"); + DestinationRegistry destinationRegistry = (DestinationRegistry) bundleContext.getService(destinationServiceServiceReference); + + Servlet servlet = new CXFNonSpringServlet(destinationRegistry, false); try { + if (properties == null) { + properties = new Properties(); + } + Properties sprops = new Properties(); + sprops.put("init-prefix", + getProp(properties, CXF_SERVLET_PREFIX + "init-prefix", "")); + sprops.put("servlet-name", + getProp(properties, CXF_SERVLET_PREFIX + "name", "cxf-osgi-transport-servlet")); + sprops.put("hide-service-list-page", + getProp(properties, CXF_SERVLET_PREFIX + "hide-service-list-page", "false")); + sprops.put("disable-address-updates", + getProp(properties, CXF_SERVLET_PREFIX + "disable-address-updates", "true")); + sprops.put("base-address", + getProp(properties, CXF_SERVLET_PREFIX + "base-address", "")); + sprops.put("service-list-path", + getProp(properties, CXF_SERVLET_PREFIX + "service-list-path", "")); + sprops.put("static-resources-list", + getProp(properties, CXF_SERVLET_PREFIX + "static-resources-list", "")); + sprops.put("redirects-list", + getProp(properties, CXF_SERVLET_PREFIX + "redirects-list", "")); + sprops.put("redirect-servlet-name", + getProp(properties, CXF_SERVLET_PREFIX + "redirect-servlet-name", "")); + sprops.put("redirect-servlet-path", + getProp(properties, CXF_SERVLET_PREFIX + "redirect-servlet-path", "")); + sprops.put("service-list-all-contexts", + getProp(properties, CXF_SERVLET_PREFIX + "service-list-all-contexts", "")); + sprops.put("service-list-page-authenticate", + getProp(properties, CXF_SERVLET_PREFIX + "service-list-page-authenticate", "false")); + sprops.put("service-list-page-authenticate-realm", + getProp(properties, CXF_SERVLET_PREFIX + "service-list-page-authenticate-realm", "karaf")); + sprops.put("use-x-forwarded-headers", + getProp(properties, CXF_SERVLET_PREFIX + "use-x-forwarded-headers", "false")); + + // Accept extra properties by default, can be disabled if it is really needed + if (Boolean.valueOf(getProp(properties, CXF_SERVLET_PREFIX + "support.extra.properties", "true").toString())) { + Enumeration keys = properties.keys(); + while (keys.hasMoreElements()) { + String nextKey = keys.nextElement().toString(); + if (!nextKey.startsWith(CXF_SERVLET_PREFIX)) { + sprops.put(nextKey, properties.get(nextKey)); + } + } + } + Hashtable servletInitParams = new Hashtable(); - String[] propNames = servletReference.getPropertyKeys(); - for (String propName : propNames) { + Enumeration keys = sprops.keys(); + + while(keys.hasMoreElements()){ + String propName = (String) keys.nextElement(); if (!FILTERED_PROPERTIES.contains(propName)) { - servletInitParams.put(propName, servletReference.getProperty(propName)); + servletInitParams.put(propName, sprops.getProperty(propName)); } } // Try to register servlet in given web container now - HttpContext httpContext = webContainer.createDefaultHttpContext(); - String alias = (String) servletReference.getProperty("alias"); webContainer.registerServlet(alias, servlet, servletInitParams, httpContext); } catch (Exception e) { log.error("Can't register servlet in web container", e); @@ -156,7 +214,7 @@ public class ServletReregistrationService { * @return web container or null */ protected WebContainer findExternalWebContainer() { - BundleContext servletBundleContext = servletReference.getBundle().getBundleContext(); + BundleContext servletBundleContext = managedServiceReference.getBundle().getBundleContext(); ServiceReference webContainerReference = servletBundleContext.getServiceReference(WebContainer.class.getName()); if (webContainerReference == null) { log.warn("Not found webContainer reference for bundle " + servletBundleContext); @@ -166,4 +224,32 @@ public class ServletReregistrationService { } } + private Dictionary obtainProperties(){ + Dictionary properties = null; + ServiceReference reference = bundleContext.getServiceReference(ConfigurationAdmin.class.getName()); + ConfigurationAdmin admin = (ConfigurationAdmin) bundleContext.getService(reference); + try { + Configuration configuration = admin.getConfiguration("org.apache.cxf.osgi"); + properties = configuration.getProperties(); + } catch (Exception e){ + log.warn("Unable to obtain cxf osgi configadmin reference.", e); + } + return properties; + } + + private Object getProp(Dictionary properties, String key, Object defaultValue) { + Object value = null; + if(properties != null){ + value = properties.get(key); + } + return value == null ? defaultValue : value; + } + + public ServiceReference getManagedServiceReference() { + return managedServiceReference; + } + + public void setManagedServiceReference(ServiceReference managedServiceReference) { + this.managedServiceReference = managedServiceReference; + } } diff --git a/distribution/adapters/osgi/features/src/main/resources/features.xml b/distribution/adapters/osgi/features/src/main/resources/features.xml index 6ead274f5a..c9c726e0c6 100755 --- a/distribution/adapters/osgi/features/src/main/resources/features.xml +++ b/distribution/adapters/osgi/features/src/main/resources/features.xml @@ -46,12 +46,21 @@
The keycloak Jetty8 adapter
keycloak-adapter-core - jetty + jetty mvn:org.keycloak/keycloak-jetty-adapter-spi/${project.version} mvn:org.keycloak/keycloak-jetty-core/${project.version} mvn:org.keycloak/keycloak-jetty81-adapter/${project.version}
+ +
The keycloak Jetty9 adapter
+ keycloak-adapter-core + jetty + mvn:org.keycloak/keycloak-jetty-adapter-spi/${project.version} + mvn:org.keycloak/keycloak-jetty-core/${project.version} + mvn:org.keycloak/keycloak-jetty92-adapter/${project.version} +
+
The keycloak JAAS configuration
keycloak-adapter-core @@ -61,7 +70,6 @@
The keycloak adapter core stuff
keycloak-osgi-adapter - keycloak-jetty8-adapter keycloak-jaas
@@ -74,4 +82,4 @@ mvn:org.apache.xbean/xbean-finder/3.18
- \ No newline at end of file + diff --git a/examples/fuse/camel/pom.xml b/examples/fuse/camel/pom.xml index e70fb23fed..47d475c56f 100755 --- a/examples/fuse/camel/pom.xml +++ b/examples/fuse/camel/pom.xml @@ -32,15 +32,21 @@ - 2.15.1 + - org.eclipse.jetty.security;version="[8.1,10)", - org.eclipse.jetty.util.security;version="[8.1,10)", - org.apache.camel;version="[2.12,3)", + javax.servlet;version="[3,4)", + javax.servlet.http;version="[3,4)", + org.apache.camel.*, + org.apache.camel;version="[2.13,3)", + org.eclipse.jetty.security;version="[8,10)", + org.eclipse.jetty.server.nio;version="[8,10)", + org.eclipse.jetty.util.security;version="[8,10)", org.keycloak.*;version="${project.version}", - *;resolution:=optional + org.osgi.service.blueprint, + org.osgi.service.blueprint.container, + org.osgi.service.event, org.keycloak.example.* @@ -63,7 +69,7 @@ ${camel.version} org.apache.camel - camel-jetty + camel-jetty9 ${camel.version} diff --git a/examples/fuse/cxf-jaxrs/pom.xml b/examples/fuse/cxf-jaxrs/pom.xml index 4600f11cb5..a07a78b990 100755 --- a/examples/fuse/cxf-jaxrs/pom.xml +++ b/examples/fuse/cxf-jaxrs/pom.xml @@ -31,7 +31,6 @@ CXF JAXRS Example - Secured in Karaf/Fuse - 3.0.4 @@ -40,9 +39,11 @@ org.apache.cxf.transport.http;version="[2.7,3.2)", org.apache.cxf.*;version="[2.7,3.2)", com.fasterxml.jackson.jaxrs.json;version="${jackson.version}", + org.eclipse.jetty.security;version="[8,10)", + org.eclipse.jetty.util.security;version="[8,10)", + org.keycloak.*;version="${project.version}", org.keycloak.adapters.jetty;version="${project.version}", - org.keycloak.adapters;version="${project.version}", - * + *;resolution:=optional org.keycloak.example.rs.* diff --git a/examples/fuse/cxf-jaxrs/src/main/resources/META-INF/cxf/bus-extensions.txt b/examples/fuse/cxf-jaxrs/src/main/resources/META-INF/cxf/bus-extensions.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/fuse/cxf-jaxrs/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/examples/fuse/cxf-jaxrs/src/main/resources/OSGI-INF/blueprint/blueprint.xml index 619b047ef3..74b5fabf41 100644 --- a/examples/fuse/cxf-jaxrs/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/examples/fuse/cxf-jaxrs/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -69,9 +69,9 @@ - - + + - \ No newline at end of file + diff --git a/examples/fuse/cxf-jaxws/pom.xml b/examples/fuse/cxf-jaxws/pom.xml index 494d7ef4cd..8923a0d2e8 100755 --- a/examples/fuse/cxf-jaxws/pom.xml +++ b/examples/fuse/cxf-jaxws/pom.xml @@ -32,7 +32,6 @@ - 3.0.4 @@ -50,7 +49,9 @@ org.apache.cxf.transport.http;version="[2.7,3.2)", org.apache.cxf.*;version="[2.7,3.2)", org.springframework.beans.factory.config, - *;resolution:=optional + org.eclipse.jetty.security;version="[8,10)", + org.eclipse.jetty.util.security;version="[8,10)", + org.keycloak.*;version="${project.version}" org.keycloak.example.ws.* diff --git a/examples/fuse/features/src/main/resources/features.xml b/examples/fuse/features/src/main/resources/features.xml index c838b02bfd..3333a4a18c 100644 --- a/examples/fuse/features/src/main/resources/features.xml +++ b/examples/fuse/features/src/main/resources/features.xml @@ -18,13 +18,32 @@ - + +
The keycloak fuse example
+ war + camel + camel-jetty9 + cxf + keycloak + keycloak-jetty9-adapter + mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version} + mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version} + mvn:org.keycloak.example.demo/product-portal-fuse-example/${project.version} + mvn:org.keycloak.example.demo/customer-portal-fuse-example/${project.version}/war + mvn:org.keycloak.example.demo/camel-endpoint-example/${project.version} + mvn:org.keycloak.example.demo/cxf-jaxws-example/${project.version} + mvn:org.keycloak.example.demo/cxf-jaxrs-example/${project.version} +
+ + +
The keycloak fuse example
war camel camel-jetty cxf keycloak + keycloak-jetty8-adapter mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version} mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version} mvn:org.keycloak.example.demo/product-portal-fuse-example/${project.version} @@ -34,4 +53,4 @@ mvn:org.keycloak.example.demo/cxf-jaxrs-example/${project.version}
-
\ No newline at end of file + diff --git a/examples/fuse/pom.xml b/examples/fuse/pom.xml index 1d89e0431e..2ecc888714 100755 --- a/examples/fuse/pom.xml +++ b/examples/fuse/pom.xml @@ -29,7 +29,10 @@ keycloak-examples-fuse-parent pom - + + 3.1.5 + 2.16.1 + customer-app-fuse product-app-fuse @@ -39,4 +42,4 @@ features - \ No newline at end of file + diff --git a/pom.xml b/pom.xml index ff731e98c0..008fefc04a 100755 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.2.0 5.1.29 4.2.0 - 3.1.2 + 4.2.4 9.3-1100-jdbc41 1.3.7 1.0.2.Final @@ -621,6 +621,11 @@ pax-web-runtime ${pax.web.version} + + org.ops4j.pax.web + pax-web-api + ${pax.web.version} + org.jboss.aesh aesh