Skip to content

Commit

Permalink
KEYCLOAK-2805 - Support for JBoss Fuse 6.3
Browse files Browse the repository at this point in the history
Upgrade of CXF, Jetty and Pax-Web required to rewrite part of the integration.
  • Loading branch information
paoloantinori authored and mposolda committed May 5, 2016
1 parent 49dc536 commit f5f3654
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 50 deletions.
17 changes: 16 additions & 1 deletion adapters/oidc/osgi-adapter/pom.xml
Expand Up @@ -31,15 +31,19 @@
<packaging>jar</packaging> <packaging>jar</packaging>


<properties> <properties>

<cxf.version>3.1.5</cxf.version>
<jetty9.version>8.1.17.v20150415</jetty9.version> <jetty9.version>8.1.17.v20150415</jetty9.version>
<keycloak.osgi.export> <keycloak.osgi.export>
org.keycloak.adapters.osgi.* org.keycloak.adapters.osgi.*
</keycloak.osgi.export> </keycloak.osgi.export>
<keycloak.osgi.import> <keycloak.osgi.import>
org.ops4j.pax.web.*;version="[3.0,4)", org.ops4j.pax.web.*;version="[3.0,5)",
javax.servlet.*;version="[2.5,4)";resolution:=optional, javax.servlet.*;version="[2.5,4)";resolution:=optional,
org.eclipse.jetty.*;version="[8.1,10)";resolution:=optional, org.eclipse.jetty.*;version="[8.1,10)";resolution:=optional,
org.keycloak.*;version="${project.version}", 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 *;resolution:=optional
</keycloak.osgi.import> </keycloak.osgi.import>
</properties> </properties>
Expand All @@ -65,12 +69,23 @@
<artifactId>pax-web-runtime</artifactId> <artifactId>pax-web-runtime</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.ops4j.pax.web</groupId>
<artifactId>pax-web-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId> <artifactId>jetty-security</artifactId>
<version>${jetty9.version}</version> <version>${jetty9.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>


<build> <build>
Expand Down
Expand Up @@ -18,15 +18,22 @@
package org.keycloak.adapters.osgi; package org.keycloak.adapters.osgi;


import java.util.Arrays; import java.util.Arrays;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import java.util.Properties;


import javax.servlet.Servlet; 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.jboss.logging.Logger;
import org.ops4j.pax.web.service.WebContainer; import org.ops4j.pax.web.service.WebContainer;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference; 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.service.http.HttpContext;
import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.osgi.util.tracker.ServiceTrackerCustomizer;
Expand All @@ -42,13 +49,15 @@
*/ */
public class ServletReregistrationService { public class ServletReregistrationService {


private static final String CXF_SERVLET_PREFIX = "org.apache.cxf.servlet.";
protected static final Logger log = Logger.getLogger(ServletReregistrationService.class); protected static final Logger log = Logger.getLogger(ServletReregistrationService.class);


private static final List<String> FILTERED_PROPERTIES = Arrays.asList("objectClass", "service.id"); private static final List<String> FILTERED_PROPERTIES = Arrays.asList("objectClass", "service.id");


private BundleContext bundleContext; private BundleContext bundleContext;
private ServiceReference servletReference; private ServiceReference managedServiceReference;
private ServiceTracker webContainerTracker; private ServiceTracker webContainerTracker;
private String alias;


public BundleContext getBundleContext() { public BundleContext getBundleContext() {
return bundleContext; return bundleContext;
Expand All @@ -58,43 +67,38 @@ public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext; this.bundleContext = bundleContext;
} }


public ServiceReference getServletReference() {
return servletReference;
}

public void setServletReference(ServiceReference servletReference) {
this.servletReference = servletReference;
}

protected ServiceTracker getWebContainerTracker() {
return webContainerTracker;
}


public void start() { public void start() {
if (servletReference == null) { if ( managedServiceReference == null) {
throw new IllegalStateException("No servlet reference provided"); 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(); WebContainer externalWebContainer = findExternalWebContainer();
if (externalWebContainer == null) { if (externalWebContainer == null) {
return; return;
} }


// Unregister servlet from external container now // Unregister servlet from external container now
try { try {
externalWebContainer.unregisterServlet(servlet); externalWebContainer.unregister(alias);
log.debug("Original servlet with alias " + getAlias() + " unregistered successfully from external web container."); log.debug("Original servlet with alias " + getAlias() + " unregistered successfully from external web container.");
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
log.warn("Can't unregister servlet due to: " + e.getMessage()); log.warn("Can't unregister servlet due to: " + e.getMessage());
} }


final Dictionary finalProperties = properties;
ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() { ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() {


@Override @Override
public Object addingService(ServiceReference webContainerServiceReference) { public Object addingService(ServiceReference webContainerServiceReference) {
WebContainer ourWebContainer = (WebContainer) bundleContext.getService(webContainerServiceReference); WebContainer ourWebContainer = (WebContainer) bundleContext.getService(webContainerServiceReference);
registerServlet(ourWebContainer, servlet); registerServlet(ourWebContainer, finalProperties);
log.debugv("Servlet with alias " + getAlias() + " registered to secured web container"); log.debugv("Servlet with alias " + getAlias() + " registered to secured web container");
return ourWebContainer; return ourWebContainer;
} }
Expand Down Expand Up @@ -122,28 +126,82 @@ public void stop() {


// Re-register servlet back to original context // Re-register servlet back to original context
WebContainer externalWebContainer = findExternalWebContainer(); WebContainer externalWebContainer = findExternalWebContainer();
Servlet servlet = (Servlet) bundleContext.getService(servletReference); registerServlet(externalWebContainer, obtainProperties());
registerServlet(externalWebContainer, servlet);
log.debug("Servlet with alias " + getAlias() + " registered back to external web container"); log.debug("Servlet with alias " + getAlias() + " registered back to external web container");
} }


private String getAlias() { 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 { 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<String, Object> servletInitParams = new Hashtable<String, Object>(); Hashtable<String, Object> servletInitParams = new Hashtable<String, Object>();
String[] propNames = servletReference.getPropertyKeys(); Enumeration keys = sprops.keys();
for (String propName : propNames) {
while(keys.hasMoreElements()){
String propName = (String) keys.nextElement();
if (!FILTERED_PROPERTIES.contains(propName)) { 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 // 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); webContainer.registerServlet(alias, servlet, servletInitParams, httpContext);
} catch (Exception e) { } catch (Exception e) {
log.error("Can't register servlet in web container", e); log.error("Can't register servlet in web container", e);
Expand All @@ -156,7 +214,7 @@ protected void registerServlet(WebContainer webContainer, Servlet servlet) {
* @return web container or null * @return web container or null
*/ */
protected WebContainer findExternalWebContainer() { protected WebContainer findExternalWebContainer() {
BundleContext servletBundleContext = servletReference.getBundle().getBundleContext(); BundleContext servletBundleContext = managedServiceReference.getBundle().getBundleContext();
ServiceReference webContainerReference = servletBundleContext.getServiceReference(WebContainer.class.getName()); ServiceReference webContainerReference = servletBundleContext.getServiceReference(WebContainer.class.getName());
if (webContainerReference == null) { if (webContainerReference == null) {
log.warn("Not found webContainer reference for bundle " + servletBundleContext); log.warn("Not found webContainer reference for bundle " + servletBundleContext);
Expand All @@ -166,4 +224,32 @@ protected WebContainer findExternalWebContainer() {
} }
} }


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;
}
} }
Expand Up @@ -46,12 +46,21 @@
<feature name="keycloak-jetty8-adapter" version="${project.version}" resolver="(obr)"> <feature name="keycloak-jetty8-adapter" version="${project.version}" resolver="(obr)">
<details>The keycloak Jetty8 adapter</details> <details>The keycloak Jetty8 adapter</details>
<feature>keycloak-adapter-core</feature> <feature>keycloak-adapter-core</feature>
<feature version="[8.1,9)">jetty</feature> <feature version="[8,9)">jetty</feature>
<bundle>mvn:org.keycloak/keycloak-jetty-adapter-spi/${project.version}</bundle> <bundle>mvn:org.keycloak/keycloak-jetty-adapter-spi/${project.version}</bundle>
<bundle>mvn:org.keycloak/keycloak-jetty-core/${project.version}</bundle> <bundle>mvn:org.keycloak/keycloak-jetty-core/${project.version}</bundle>
<bundle>mvn:org.keycloak/keycloak-jetty81-adapter/${project.version}</bundle> <bundle>mvn:org.keycloak/keycloak-jetty81-adapter/${project.version}</bundle>
</feature> </feature>


<feature name="keycloak-jetty9-adapter" version="${project.version}" resolver="(obr)">
<details>The keycloak Jetty9 adapter</details>
<feature>keycloak-adapter-core</feature>
<feature version="[9,10)">jetty</feature>
<bundle>mvn:org.keycloak/keycloak-jetty-adapter-spi/${project.version}</bundle>
<bundle>mvn:org.keycloak/keycloak-jetty-core/${project.version}</bundle>
<bundle>mvn:org.keycloak/keycloak-jetty92-adapter/${project.version}</bundle>
</feature>

<feature name="keycloak-jaas" version="${project.version}" resolver="(obr)"> <feature name="keycloak-jaas" version="${project.version}" resolver="(obr)">
<details>The keycloak JAAS configuration</details> <details>The keycloak JAAS configuration</details>
<feature>keycloak-adapter-core</feature> <feature>keycloak-adapter-core</feature>
Expand All @@ -61,7 +70,6 @@
<feature name="keycloak" version="${project.version}" resolver="(obr)"> <feature name="keycloak" version="${project.version}" resolver="(obr)">
<details>The keycloak adapter core stuff</details> <details>The keycloak adapter core stuff</details>
<feature>keycloak-osgi-adapter</feature> <feature>keycloak-osgi-adapter</feature>
<feature>keycloak-jetty8-adapter</feature>
<feature>keycloak-jaas</feature> <feature>keycloak-jaas</feature>
</feature> </feature>


Expand All @@ -74,4 +82,4 @@
<bundle>mvn:org.apache.xbean/xbean-finder/3.18</bundle> <bundle>mvn:org.apache.xbean/xbean-finder/3.18</bundle>
</feature> </feature>


</features> </features>
18 changes: 12 additions & 6 deletions examples/fuse/camel/pom.xml
Expand Up @@ -32,15 +32,21 @@
<description/> <description/>


<properties> <properties>
<camel.version>2.15.1</camel.version>
<keycloak.osgi.export> <keycloak.osgi.export>
</keycloak.osgi.export> </keycloak.osgi.export>
<keycloak.osgi.import> <keycloak.osgi.import>
org.eclipse.jetty.security;version="[8.1,10)", javax.servlet;version="[3,4)",
org.eclipse.jetty.util.security;version="[8.1,10)", javax.servlet.http;version="[3,4)",
org.apache.camel;version="[2.12,3)", 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}", org.keycloak.*;version="${project.version}",
*;resolution:=optional org.osgi.service.blueprint,
org.osgi.service.blueprint.container,
org.osgi.service.event,
</keycloak.osgi.import> </keycloak.osgi.import>
<keycloak.osgi.private> <keycloak.osgi.private>
org.keycloak.example.* org.keycloak.example.*
Expand All @@ -63,7 +69,7 @@
<version>${camel.version}</version> <version>${camel.version}</version>
</dependency> </dependency>
<dependency><groupId>org.apache.camel</groupId> <dependency><groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId> <artifactId>camel-jetty9</artifactId>
<version>${camel.version}</version> <version>${camel.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
Expand Down
7 changes: 4 additions & 3 deletions examples/fuse/cxf-jaxrs/pom.xml
Expand Up @@ -31,7 +31,6 @@
<name>CXF JAXRS Example - Secured in Karaf/Fuse</name> <name>CXF JAXRS Example - Secured in Karaf/Fuse</name>


<properties> <properties>
<cxf.version>3.0.4</cxf.version>
<keycloak.osgi.export> <keycloak.osgi.export>
</keycloak.osgi.export> </keycloak.osgi.export>
<keycloak.osgi.import> <keycloak.osgi.import>
Expand All @@ -40,9 +39,11 @@
org.apache.cxf.transport.http;version="[2.7,3.2)", org.apache.cxf.transport.http;version="[2.7,3.2)",
org.apache.cxf.*;version="[2.7,3.2)", org.apache.cxf.*;version="[2.7,3.2)",
com.fasterxml.jackson.jaxrs.json;version="${jackson.version}", 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.jetty;version="${project.version}",
org.keycloak.adapters;version="${project.version}", *;resolution:=optional
*
</keycloak.osgi.import> </keycloak.osgi.import>
<keycloak.osgi.private> <keycloak.osgi.private>
org.keycloak.example.rs.* org.keycloak.example.rs.*
Expand Down
Empty file.
Expand Up @@ -69,9 +69,9 @@
<bean id="defaultCxfReregistration" class="org.keycloak.adapters.osgi.ServletReregistrationService" depends-on="cxfKeycloakPaxWebIntegration" <bean id="defaultCxfReregistration" class="org.keycloak.adapters.osgi.ServletReregistrationService" depends-on="cxfKeycloakPaxWebIntegration"
init-method="start" destroy-method="stop"> init-method="start" destroy-method="stop">
<property name="bundleContext" ref="blueprintBundleContext" /> <property name="bundleContext" ref="blueprintBundleContext" />
<property name="servletReference"> <property name="managedServiceReference">
<reference interface="javax.servlet.Servlet" filter="(alias=/cxf)" timeout="5000" /> <reference interface="org.osgi.service.cm.ManagedService" filter="(service.pid=org.apache.cxf.osgi)" timeout="5000" />
</property> </property>
</bean> </bean>


</blueprint> </blueprint>

0 comments on commit f5f3654

Please sign in to comment.