KEYCLOAK-539 Fuse adapter. OSGI bundling. OSGI headers in keycloak adapter maven artifacts. Rename package in jetty-core

This commit is contained in:
mposolda 2015-01-06 18:04:47 +01:00
parent e4b7dd2df3
commit d928c26e27
72 changed files with 2666 additions and 115 deletions

View file

@ -11,11 +11,19 @@
<artifactId>keycloak-core</artifactId> <artifactId>keycloak-core</artifactId>
<name>Keycloak Core</name> <name>Keycloak Core</name>
<packaging>jar</packaging>
<description/> <description/>
<properties> <properties>
<timestamp>${maven.build.timestamp}</timestamp> <timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format> <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
<keycloak.osgi.export>
org.keycloak.*
</keycloak.osgi.export>
<keycloak.osgi.import>
net.iharder;version=${base64.version},
*;resolution:=optional
</keycloak.osgi.import>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
@ -60,6 +68,39 @@
<target>${maven.compiler.target}</target> <target>${maven.compiler.target}</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View file

@ -93,6 +93,12 @@
<exclude name="**/README.md"/> <exclude name="**/README.md"/>
</fileset> </fileset>
</copy> </copy>
<copy todir="target/examples/fuse" overwrite="true">
<fileset dir="../../examples/fuse">
<exclude name="**/target/**"/>
<exclude name="**/*.iml"/>
</fileset>
</copy>
<copy file="../../examples/README.md" tofile="target/examples/README.md"/> <copy file="../../examples/README.md" tofile="target/examples/README.md"/>
<move file="target/examples/unconfigured-demo/README.md.unconfigured" tofile="target/examples/unconfigured-demo/README.md"/> <move file="target/examples/unconfigured-demo/README.md.unconfigured" tofile="target/examples/unconfigured-demo/README.md"/>
<move file="target/examples/unconfigured-demo/customer-app/src/main/webapp/WEB-INF/web.xml.unconfigured" tofile="target/examples/unconfigured-demo/customer-app/src/main/webapp/WEB-INF/web.xml"/> <move file="target/examples/unconfigured-demo/customer-app/src/main/webapp/WEB-INF/web.xml.unconfigured" tofile="target/examples/unconfigured-demo/customer-app/src/main/webapp/WEB-INF/web.xml"/>

View file

@ -1,15 +1,53 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0" name="keycloak-${project.version}"> <features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0" name="keycloak-${project.version}">
<feature name="keycloak-core-adapter" version="${project.version}" resolver="(obr)"> <feature name="keycloak-adapter-core" version="${project.version}" resolver="(obr)">
<details>The keycloak core adapter stuff</details> <details>The keycloak adapter core stuff</details>
<bundle>mvn:org.keycloak/keycloak-osgi-core-adapter/${project.version}</bundle> <bundle dependency="true">mvn:org.keycloak/keycloak-osgi-thirdparty/${project.version}</bundle>
<bundle dependency="true">mvn:org.bouncycastle/bcprov-jdk16/${bouncycastle.version}</bundle>
<bundle dependency="true">mvn:org.codehaus.jackson/jackson-core-asl/${jackson.version}</bundle>
<bundle dependency="true">mvn:org.codehaus.jackson/jackson-mapper-asl/${jackson.version}</bundle>
<bundle dependency="true">mvn:org.codehaus.jackson/jackson-xc/${jackson.version}</bundle>
<bundle dependency="true">mvn:org.jboss.logging/jboss-logging/${jboss.logging.version}</bundle>
<bundle>mvn:org.keycloak/keycloak-core/${project.version}</bundle>
<bundle>mvn:org.keycloak/keycloak-adapter-core/${project.version}</bundle>
</feature>
<feature name="keycloak-osgi-adapter" version="${project.version}" resolver="(obr)">
<details>The keycloak adapter core stuff</details>
<feature>keycloak-adapter-core</feature>
<feature version="[2.3,4)">http-whiteboard</feature>
<bundle>mvn:org.keycloak/keycloak-osgi-adapter/${project.version}</bundle>
</feature>
<feature name="keycloak-jetty8-adapter" version="${project.version}" resolver="(obr)">
<details>The keycloak Jetty8 adapter</details>
<feature>keycloak-adapter-core</feature>
<feature version="[8.1,9)">jetty</feature>
<bundle>mvn:org.keycloak/keycloak-jetty-core/${project.version}</bundle>
<bundle>mvn:org.keycloak/keycloak-jetty81-adapter/${project.version}</bundle>
</feature> </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-core-adapter</feature> <feature>keycloak-adapter-core</feature>
<bundle>mvn:org.keycloak/keycloak-osgi-jaas/${project.version}</bundle> <bundle>mvn:org.keycloak/keycloak-osgi-jaas/${project.version}</bundle>
</feature> </feature>
<feature name="keycloak" version="${project.version}" resolver="(obr)">
<details>The keycloak adapter core stuff</details>
<feature>keycloak-osgi-adapter</feature>
<feature>keycloak-jetty8-adapter</feature>
<feature>keycloak-jaas</feature>
</feature>
<!-- This is just simplification to upgrade paxweb to 3.1.2 in JBoss Fuse 6.1 or Karaf 2.3.X environment -->
<feature name="keycloak-pax-web-upgrade" version="${project.version}" resolver="(obr)">
<details>This is just simplification to upgrade paxweb to 3.1.2 in JBoss Fuse 6.1 or Karaf 2.3.X environment</details>
<bundle>mvn:org.ow2.asm/asm-all/5.0</bundle>
<bundle>mvn:org.apache.xbean/xbean-bundleutils/3.18</bundle>
<bundle>mvn:org.apache.xbean/xbean-reflect/3.18</bundle>
<bundle>mvn:org.apache.xbean/xbean-finder/3.18</bundle>
</feature>
</features> </features>

View file

@ -7,7 +7,7 @@
<version>1.2.0.Beta1-SNAPSHOT</version> <version>1.2.0.Beta1-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath> <relativePath>../../../pom.xml</relativePath>
</parent> </parent>
<name>Keycloak OSGI JAAS</name> <name>Keycloak OSGI JAAS Realm Configuration</name>
<description/> <description/>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -53,7 +53,7 @@
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency> <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Transitive>false</Embed-Transitive> <Embed-Transitive>false</Embed-Transitive>
<Bundle-ClassPath>.</Bundle-ClassPath> --> <Bundle-ClassPath>.</Bundle-ClassPath> -->
<Bundle-Name>${project.description}</Bundle-Name> <Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName> <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package> <Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package> <Export-Package>${keycloak.osgi.export}</Export-Package>

View file

@ -17,7 +17,7 @@
<modules> <modules>
<module>features</module> <module>features</module>
<module>jaas</module> <module>jaas</module>
<module>core-adapter</module> <module>thirdparty</module>
</modules> </modules>
</project> </project>

View file

@ -7,17 +7,18 @@
<version>1.2.0.Beta1-SNAPSHOT</version> <version>1.2.0.Beta1-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath> <relativePath>../../../pom.xml</relativePath>
</parent> </parent>
<name>Keycloak OSGI Core Adapter Integration</name>
<description/> <name>Keycloak OSGI Thirdparty</name>
<description>Keycloak OSGI bundling for 3rd party libs without OSGI headers in manifest</description>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-osgi-core-adapter</artifactId> <artifactId>keycloak-osgi-thirdparty</artifactId>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<properties> <properties>
<keycloak.osgi.export> <keycloak.osgi.export>
org.keycloak.adapters.jaas, net.iharder;version="${base64.version}",
org.keycloak.adapters org.apache.http.*;version=${keycloak.apache.httpcomponents.version}
</keycloak.osgi.export> </keycloak.osgi.export>
<keycloak.osgi.import> <keycloak.osgi.import>
*;resolution:=optional *;resolution:=optional
@ -26,45 +27,19 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>net.iharder</groupId>
<artifactId>keycloak-core</artifactId> <artifactId>base64</artifactId>
<version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>keycloak-adapter-core</artifactId> <artifactId>httpcore</artifactId>
<version>${project.version}</version> <version>${keycloak.apache.httpcomponents.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>${keycloak.apache.httpcomponents.version}</version> <version>${keycloak.apache.httpcomponents.version}</version>
</dependency> </dependency>
<dependency>
<groupId>net.iharder</groupId>
<artifactId>base64</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -84,14 +59,14 @@
</executions> </executions>
<configuration> <configuration>
<instructions> <instructions>
<Embed-Dependency>*;scope=compile|runtime;artifactId=!keycloak-adapter-core</Embed-Dependency> <Embed-Dependency>*;scope=compile|runtime;artifactId=!httpclient|httpcore|base64</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive> <Embed-Transitive>true</Embed-Transitive>
<Bundle-ClassPath>.</Bundle-ClassPath> <Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.description}</Bundle-Name> <Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName> <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package> <Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package> <Export-Package>${keycloak.osgi.export}</Export-Package>
<Implementation-Title>keycloak</Implementation-Title> <Implementation-Title>${project.name}</Implementation-Title>
<Implementation-Version>${project.version}</Implementation-Version> <Implementation-Version>${project.version}</Implementation-Version>
</instructions> </instructions>
</configuration> </configuration>

33
examples/fuse/README.md Normal file
View file

@ -0,0 +1,33 @@
1) First step is to run Keycloak server on localhost:8080 and import realm "demo" from the file testrealm.json in this directory (Directory "fuse").
Running example on Karaf 3.0.2
------------------------------
feature:repo-add mvn:org.apache.camel.karaf/apache-camel/2.12.5/xml/features
feature:repo-add mvn:org.apache.cxf.karaf/apache-cxf/2.7.14/xml/features
feature:repo-add mvn:org.keycloak/keycloak-osgi-features/1.1.0.Final/xml/features
feature:repo-add mvn:org.keycloak.example.demo/keycloak-fuse-example-features/1.1.0.Final/xml/features
feature:install keycloak-fuse-example
Running example on JBoss Fuse 6.1.0.redhat-379
----------------------------------------------
features:uninstall pax-war
features:uninstall pax-http-whiteboard
features:uninstall pax-http
features:uninstall pax-jetty
features:removeurl mvn:org.ops4j.pax.web/pax-web-features/3.0.6/xml/features
features:addurl mvn:org.ops4j.pax.web/pax-web-features/3.1.2/xml/features
features:addurl mvn:org.keycloak/keycloak-osgi-features/1.1.0.Final/xml/features
features:addurl mvn:org.keycloak.example.demo/keycloak-fuse-example-features/1.1.0.Final/xml/features
features:install keycloak-pax-web-upgrade
features:install pax-http-whiteboard/3.1.2
features:install pax-war/3.1.2
features:uninstall cxf
features:install cxf
features:install keycloak-fuse-example

View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>camel-endpoint-example</artifactId>
<packaging>bundle</packaging>
<name>Camel endpoint example - Secured in Karaf/Fuse</name>
<description/>
<properties>
<camel.version>2.12.5</camel.version>
<keycloak.osgi.export>
</keycloak.osgi.export>
<keycloak.osgi.import>
org.eclipse.jetty.security;version="[8.1,10)",
org.eclipse.jetty.util.security;version="[8.1,10)",
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
<keycloak.osgi.private>
org.keycloak.example.*
</keycloak.osgi.private>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-blueprint</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency><groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId>
<version>${camel.version}</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Private-Package>${keycloak.osgi.private}</Private-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,15 @@
package org.keycloak.example;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class CamelHelloBean {
public String hello() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return "Hello admin! It's " + sdf.format(new Date());
}
}

View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<bean id="kcAdapterConfig" class="org.keycloak.representations.adapters.config.AdapterConfig">
<property name="realm" value="demo"/>
<property name="resource" value="admin-camel-endpoint"/>
<property name="realmKey" value="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB"/>
<property name="bearerOnly" value="true"/>
<property name="sslRequired" value="EXTERNAL"/>
</bean>
<bean id="keycloakAuthenticator" class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
<property name="adapterConfig" ref="kcAdapterConfig"/>
</bean>
<bean id="constraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="Customers"/>
<property name="roles">
<list>
<value>admin</value>
</list>
</property>
<property name="authenticate" value="true"/>
<property name="dataConstraint" value="0"/>
</bean>
<bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="constraint"/>
<property name="pathSpec" value="/*"/>
</bean>
<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<property name="authenticator" ref="keycloakAuthenticator" />
<property name="constraintMappings">
<list>
<ref component-id="constraintMapping" />
</list>
</property>
<property name="authMethod" value="BASIC"/>
<property name="realmName" value="does-not-matter"/>
</bean>
<bean id="sessionHandler" class="org.keycloak.adapters.jetty.core.WrappingSessionHandler">
<property name="handler" ref="securityHandler" />
</bean>
<bean id="helloBean" class="org.keycloak.example.CamelHelloBean" />
<camelContext id="blueprintContext"
trace="false"
xmlns="http://camel.apache.org/schema/blueprint">
<route id="httpBridge">
<from uri="jetty:http://0.0.0.0:8383/admin-camel-endpoint?handlers=sessionHandler&amp;matchOnUriPrefix=true" />
<setBody>
<method ref="helloBean" method="hello"/>
</setBody>
<log message="The message from camel endpoint contains ${body}"/>
<to uri="mock:result"/>
</route>
</camelContext>
</blueprint>

View file

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>customer-portal-fuse-example</artifactId>
<packaging>war</packaging>
<name>Customer Portal - Secured in Karaf/Fuse</name>
<description/>
<properties>
<keycloak.osgi.export>
</keycloak.osgi.export>
<keycloak.osgi.import>
org.apache.http.*;version=${keycloak.apache.httpcomponents.version},
javax.servlet.*;version="[2.5,4)",
org.keycloak.adapters.jetty;version="${project.version}",
org.keycloak.adapters;version="${project.version}",
org.keycloak.constants;version="${project.version}",
org.keycloak.util;version="${project.version}",
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
<keycloak.osgi.private>
org.keycloak.example.*
</keycloak.osgi.private>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${keycloak.apache.httpcomponents.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>customer-portal-fuse</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${basedir}/target/classes/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
<instructions>
<Webapp-Context>customer-portal</Webapp-Context>
<Web-ContextPath>customer-portal</Web-ContextPath>
<Embed-Directory>WEB-INF/lib</Embed-Directory>
<Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Private-Package>${keycloak.osgi.private}</Private-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,74 @@
package org.keycloak.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.http.HttpServletRequest;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.HttpClientBuilder;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class CamelClient {
public static String sendRequest(HttpServletRequest req) throws CxfRsClient.Failure {
KeycloakSecurityContext session = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
HttpClient client = new HttpClientBuilder()
.disableTrustManager().build();
try {
HttpGet get = new HttpGet("http://localhost:8383/admin-camel-endpoint");
get.addHeader("Authorization", "Bearer " + session.getTokenString());
try {
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() != 200) {
return "There was a failure processing request. You either didn't configure Keycloak properly or you don't have enought permission? Status code is "
+ response.getStatusLine().getStatusCode();
}
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
try {
return getStringFromInputStream(is);
} finally {
is.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
} finally {
client.getConnectionManager().shutdown();
}
}
private static String getStringFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
return sb.toString();
}
}

View file

@ -0,0 +1,75 @@
package org.keycloak.example;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.HttpClientBuilder;
import org.keycloak.representations.IDToken;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.UriUtils;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class CxfRsClient {
static class TypedList extends ArrayList<String> {
}
public static class Failure extends Exception {
private int status;
public Failure(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
}
public static IDToken getIDToken(HttpServletRequest req) {
KeycloakSecurityContext session = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
return session.getIdToken();
}
public static List<String> getCustomers(HttpServletRequest req) throws Failure {
KeycloakSecurityContext session = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
HttpClient client = new HttpClientBuilder()
.disableTrustManager().build();
try {
HttpGet get = new HttpGet(UriUtils.getOrigin(req.getRequestURL().toString()) + "/cxf/customerservice/customers");
get.addHeader("Authorization", "Bearer " + session.getTokenString());
try {
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() != 200) {
throw new Failure(response.getStatusLine().getStatusCode());
}
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
try {
return JsonSerialization.readValue(is, TypedList.class);
} finally {
is.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
} finally {
client.getConnectionManager().shutdown();
}
}
}

View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="securityHandler">
<Set name="authenticator">
<New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
</New>
</Set>
</Get>
</Configure>

View file

@ -0,0 +1,10 @@
{
"realm": "demo",
"resource": "customer-portal",
"realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required" : "external",
"credentials": {
"secret": "password"
}
}

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<module-name>customer-portal</module-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<security-constraint>
<web-resource-collection>
<web-resource-name>Customers</web-resource-name>
<url-pattern>/customers/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>does-not-matter</realm-name>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
</web-app>

View file

@ -0,0 +1,15 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%@ page import="org.keycloak.constants.ServiceUrlConstants" %>
<%@ page import="org.keycloak.example.CamelClient" %>
<%@ page import="org.keycloak.representations.IDToken" %>
<html>
<head>
<title>Camel page</title>
</head>
<body bgcolor="#E3F6CE">
<p>You will receive info from camel endpoint. Endpoint is accessible just for admin user</p>
<p>Response from camel: <b><%= CamelClient.sendRequest(request) %></b> </p>
<br><br>
</body>
</html>

View file

@ -0,0 +1,50 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%@ page import="org.keycloak.constants.ServiceUrlConstants" %>
<%@ page import="org.keycloak.example.CxfRsClient" %>
<%@ page import="org.keycloak.representations.IDToken" %>
<%@ page import="org.keycloak.util.KeycloakUriBuilder" %>
<%@ page session="false" %>
<html>
<head>
<title>Customer View Page</title>
</head>
<body bgcolor="#E3F6CE">
<%
String logoutUri = KeycloakUriBuilder.fromUri("http://localhost:8080/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
.queryParam("redirect_uri", "http://localhost:8181/customer-portal").build("demo").toString();
String acctUri = KeycloakUriBuilder.fromUri("http://localhost:8080/auth").path(ServiceUrlConstants.ACCOUNT_SERVICE_PATH)
.queryParam("referrer", "customer-portal").build("demo").toString();
IDToken idToken = CxfRsClient.getIDToken(request);
%>
<p>Goto: <a href="/product-portal">products</a> | <a href="<%=logoutUri%>">logout</a> | <a
href="<%=acctUri%>">manage acct</a></p>
Servlet User Principal <b><%=request.getUserPrincipal().getName()%>
</b> made this request.
<p><b>Caller IDToken values</b> (<i>You can specify what is returned in IDToken in the customer-portal claims page in the admin console</i>:</p>
<p>Username: <%=idToken.getPreferredUsername()%></p>
<p>Email: <%=idToken.getEmail()%></p>
<p>Full Name: <%=idToken.getName()%></p>
<p>First: <%=idToken.getGivenName()%></p>
<p>Last: <%=idToken.getFamilyName()%></p>
<h2>Customer Listing</h2>
<%
java.util.List<String> list = null;
try {
list = CxfRsClient.getCustomers(request);
} catch (CxfRsClient.Failure failure) {
out.println("There was a failure processing request. You either didn't configure Keycloak properly, or maybe" +
"you just forgot to secure the cxf ws service?");
out.println("Status from cxf ws service invocation was: " + failure.getStatus());
return;
}
for (String cust : list) {
out.print("<p>");
out.print(cust);
out.println("</p>");
}
%>
<br><br>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Customer portal on Karaf/Fuse</title>
</head>
<body bgcolor="#E3F6CE">
<h1>Customer Portal</h1>
<p><a href="customers/cxf-ws.jsp">Customer Listing - CXF WS endpoint</a></p>
<p><a href="customers/camel.jsp">Admin Interface - Apache Camel endpoint</a></p>
</body>
</html>

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>cxf-jaxrs-example</artifactId>
<packaging>bundle</packaging>
<name>CXF JAXRS Example - Secured in Karaf/Fuse</name>
<properties>
<cxf.version>2.7.14</cxf.version>
<keycloak.osgi.export>
</keycloak.osgi.export>
<keycloak.osgi.import>
META-INF.cxf,
META-INF.cxf.osgi,
org.apache.cxf.bus,
org.apache.cxf.bus.spring,
org.apache.cxf.bus.resource,
org.apache.cxf.resource,
org.apache.cxf.jaxrs,
org.apache.cxf.transport.http,
org.codehaus.jackson.jaxrs;version="${jackson.version}",
org.keycloak.adapters.jetty;version="${project.version}",
org.keycloak.adapters;version="${project.version}",
*
</keycloak.osgi.import>
<keycloak.osgi.private>
org.keycloak.example.rs.*
</keycloak.osgi.private>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Private-Package>${keycloak.osgi.private}</Private-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,30 @@
package org.keycloak.example.rs;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@Path("/customers")
public class CxfCustomerService {
@GET
@Produces("application/json")
public List<String> getCustomers() {
ArrayList<String> rtn = new ArrayList<String>();
rtn.add("Bill Burke");
rtn.add("Stian Thorgersen");
rtn.add("Stan Silvert");
rtn.add("Gabriel Cardoso");
rtn.add("Viliam Rockai");
rtn.add("Marek Posolda");
rtn.add("Boleslaw Dawidowicz");
return rtn;
}
}

View file

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<!-- JAXRS Application -->
<bean id="customerBean" class="org.keycloak.example.rs.CxfCustomerService" />
<jaxrs:server id="cxfJaxrsServer" address="/customerservice">
<jaxrs:providers>
<!--<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />-->
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</jaxrs:providers>
<jaxrs:serviceBeans>
<ref component-id="customerBean" />
</jaxrs:serviceBeans>
</jaxrs:server>
<!-- Securing of whole /cxf context by unregister default cxf servlet from paxweb and re-register with applied security constraints -->
<cm:property-placeholder persistent-id="org.apache.cxf.osgi" id="cxfOsgiPropertiesKCSecured">
<cm:default-properties>
<cm:property name="org.apache.cxf.servlet.context" value="/cxf"/>
<cm:property name="org.apache.cxf.servlet.name" value="cxf-osgi-transport-servlet"/>
<cm:property name="org.apache.cxf.servlet.hide-service-list-page" value="false"/>
<cm:property name="org.apache.cxf.servlet.disable-address-updates" value="false"/>
<cm:property name="org.apache.cxf.servlet.base-address" value=""/>
<cm:property name="org.apache.cxf.servlet.service-list-path" value=""/>
<cm:property name="org.apache.cxf.servlet.static-resources-list" value=""/>
<cm:property name="org.apache.cxf.servlet.redirects-list" value=""/>
<cm:property name="org.apache.cxf.servlet.redirect-servlet-name" value=""/>
<cm:property name="org.apache.cxf.servlet.redirect-servlet-path" value=""/>
<cm:property name="org.apache.cxf.servlet.service-list-all-contexts" value=""/>
<cm:property name="org.apache.cxf.servlet.service-list-page-authenticate" value="false"/>
<cm:property name="org.apache.cxf.servlet.service-list-page-authenticate-realm" value="karaf"/>
</cm:default-properties>
</cm:property-placeholder>
<bean id="cxfConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint">
<bean class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="cst1"/>
<property name="roles">
<list>
<value>user</value>
</list>
</property>
<property name="authenticate" value="true"/>
<property name="dataConstraint" value="0"/>
</bean>
</property>
<property name="pathSpec" value="/cxf/*"/>
</bean>
<bean id="cxfKeycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.PaxWebIntegrationService"
init-method="start" destroy-method="stop">
<property name="bundleContext" ref="blueprintBundleContext" />
<property name="jettyWebXmlLocation" value="/WEB-INF/jetty-web.xml" />
<property name="constraintMappings">
<list>
<ref component-id="cxfConstraintMapping" />
</list>
</property>
</bean>
<bean id="defaultCxfUnregistration" class="org.keycloak.adapters.osgi.ServletUnregistrationService"
init-method="start" destroy-method="stop">
<property name="bundleContext" ref="blueprintBundleContext" />
<property name="servletReference">
<reference interface="javax.servlet.Servlet" component-name="osgiServlet" />
</property>
</bean>
<bean id="osgiServletKCSecured" class="org.apache.cxf.transport.servlet.CXFNonSpringServlet" depends-on="cxfKeycloakPaxWebIntegration defaultCxfUnregistration">
<argument>
<reference interface="org.apache.cxf.transport.http.DestinationRegistry" timeout="5000"/>
</argument>
<argument value="false"/>
</bean>
<service ref="osgiServletKCSecured" interface="javax.servlet.Servlet">
<service-properties>
<entry key="alias" value="${org.apache.cxf.servlet.context}"/>
<entry key="servlet-name" value="${org.apache.cxf.servlet.name}"/>
<entry key="hide-service-list-page" value="${org.apache.cxf.servlet.hide-service-list-page}"/>
<entry key="disable-address-updates" value="${org.apache.cxf.servlet.disable-address-updates}"/>
<entry key="base-address" value="${org.apache.cxf.servlet.base-address}"/>
<entry key="service-list-path" value="${org.apache.cxf.servlet.service-list-path}"/>
<entry key="static-resources-list" value="${org.apache.cxf.servlet.static-resources-list}"/>
<entry key="redirects-list" value="${org.apache.cxf.servlet.redirects-list}"/>
<entry key="redirect-servlet-name" value="${org.apache.cxf.servlet.redirect-servlet-name}"/>
<entry key="redirect-servlet-path" value="${org.apache.cxf.servlet.redirect-servlet-path}"/>
<entry key="service-list-all-contexts" value="${org.apache.cxf.servlet.service-list-all-contexts}"/>
<entry key="service-list-page-authenticate" value="${org.apache.cxf.servlet.service-list-page-authenticate}"/>
<entry key="service-list-page-authenticate-realm" value="${org.apache.cxf.servlet.service-list-page-authenticate-realm}"/>
</service-properties>
</service>
</blueprint>

View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="securityHandler">
<Set name="authenticator">
<New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
</New>
</Set>
</Get>
</Configure>

View file

@ -0,0 +1,10 @@
{
"realm": "demo",
"resource": "builtin-cxf-app",
"realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required" : "external",
"credentials": {
"secret": "password"
}
}

View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>cxf-jaxws-example</artifactId>
<packaging>bundle</packaging>
<name>CXF JAXWS Example - Secured in Karaf/Fuse</name>
<description/>
<properties>
<cxf.version>2.7.14</cxf.version>
<keycloak.osgi.export>
</keycloak.osgi.export>
<keycloak.osgi.import>
javax.jws;resolution:=optional,
javax.wsdl,
javax.xml.bind,
javax.xml.bind.annotation,
javax.xml.namespace,
javax.xml.ws,
META-INF.cxf,
META-INF.cxf.osgi,
org.apache.cxf.bus,
org.apache.cxf.bus.spring,
org.apache.cxf.bus.resource,
org.apache.cxf.configuration.spring,
org.apache.cxf.resource,
org.apache.cxf.jaxws,
org.apache.cxf.transport.http,
org.springframework.beans.factory.config,
*;resolution:=optional
</keycloak.osgi.import>
<keycloak.osgi.private>
org.keycloak.example.ws.*
</keycloak.osgi.private>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-ws-metadata_2.0_spec</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jaxws_2.2_spec</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Private-Package>${keycloak.osgi.private}</Private-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,27 @@
package org.keycloak.example.ws;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import org.keycloak.example.ws.types.ObjectFactory;
@WebService
@XmlSeeAlso({ObjectFactory.class})
public interface Person {
@RequestWrapper(localName = "GetPerson", className = "GetPerson")
@ResponseWrapper(localName = "GetPersonResponse", className = "GetPersonResponse")
@WebMethod(operationName = "GetPerson")
public void getPerson(
@WebParam(mode = WebParam.Mode.INOUT, name = "personId")
javax.xml.ws.Holder<String> personId,
@WebParam(mode = WebParam.Mode.OUT, name = "ssn")
javax.xml.ws.Holder<String> ssn,
@WebParam(mode = WebParam.Mode.OUT, name = "name")
javax.xml.ws.Holder<String> name
) throws UnknownPersonFault;
}

View file

@ -0,0 +1,22 @@
package org.keycloak.example.ws;
import javax.jws.WebService;
import javax.xml.ws.Holder;
@WebService(serviceName = "PersonService", endpointInterface = "org.keycloak.example.ws.Person")
public class PersonImpl implements Person {
public void getPerson(Holder<String> personId, Holder<String> ssn, Holder<String> name)
throws UnknownPersonFault
{
if (personId.value == null || personId.value.length() == 0) {
org.keycloak.example.ws.types.UnknownPersonFault fault = new org.keycloak.example.ws.types.UnknownPersonFault();
fault.setPersonId(personId.value);
throw new UnknownPersonFault(null,fault);
} else {
name.value = "John Doe";
ssn.value = "123-456-7890";
}
}
}

View file

@ -0,0 +1,36 @@
package org.keycloak.example.ws;
import javax.xml.ws.WebFault;
@WebFault(name = "UnknownPersonFault")
public class UnknownPersonFault extends Exception {
public static final long serialVersionUID = 20081110144906L;
private org.keycloak.example.ws.types.UnknownPersonFault unknownPersonFault;
public UnknownPersonFault() {
super();
}
public UnknownPersonFault(String message) {
super(message);
}
public UnknownPersonFault(String message, Throwable cause) {
super(message, cause);
}
public UnknownPersonFault(String message, org.keycloak.example.ws.types.UnknownPersonFault unknownPersonFault) {
super(message);
this.unknownPersonFault = unknownPersonFault;
}
public UnknownPersonFault(String message, org.keycloak.example.ws.types.UnknownPersonFault unknownPersonFault, Throwable cause) {
super(message, cause);
this.unknownPersonFault = unknownPersonFault;
}
public org.keycloak.example.ws.types.UnknownPersonFault getFaultInfo() {
return this.unknownPersonFault;
}
}

View file

@ -0,0 +1,64 @@
package org.keycloak.example.ws.types;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="personId" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"personId"
})
@XmlRootElement(name = "GetPerson")
public class GetPerson {
@XmlElement(required = true)
protected String personId;
/**
* Gets the value of the personId property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPersonId() {
return personId;
}
/**
* Sets the value of the personId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPersonId(String value) {
this.personId = value;
}
}

View file

@ -0,0 +1,120 @@
package org.keycloak.example.ws.types;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="personId" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="ssn" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"personId",
"ssn",
"name"
})
@XmlRootElement(name = "GetPersonResponse")
public class GetPersonResponse {
@XmlElement(required = true)
protected String personId;
@XmlElement(required = true)
protected String ssn;
@XmlElement(required = true)
protected String name;
/**
* Gets the value of the personId property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPersonId() {
return personId;
}
/**
* Sets the value of the personId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPersonId(String value) {
this.personId = value;
}
/**
* Gets the value of the ssn property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getSsn() {
return ssn;
}
/**
* Sets the value of the ssn property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setSsn(String value) {
this.ssn = value;
}
/**
* Gets the value of the name property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setName(String value) {
this.name = value;
}
}

View file

@ -0,0 +1,56 @@
package org.keycloak.example.ws.types;
import javax.xml.bind.annotation.XmlRegistry;
/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the org.apache.servicemix.samples.wsdl_first.types package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
@XmlRegistry
public class ObjectFactory {
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.servicemix.samples.wsdl_first.types
*
*/
public ObjectFactory() {
}
/**
* Create an instance of {@link GetPersonResponse }
*
*/
public GetPersonResponse createGetPersonResponse() {
return new GetPersonResponse();
}
/**
* Create an instance of {@link GetPerson }
*
*/
public GetPerson createGetPerson() {
return new GetPerson();
}
/**
* Create an instance of {@link UnknownPersonFault }
*
*/
public UnknownPersonFault createUnknownPersonFault() {
return new UnknownPersonFault();
}
}

View file

@ -0,0 +1,64 @@
package org.keycloak.example.ws.types;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="personId" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"personId"
})
@XmlRootElement(name = "UnknownPersonFault")
public class UnknownPersonFault {
@XmlElement(required = true)
protected String personId;
/**
* Gets the value of the personId property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPersonId() {
return personId;
}
/**
* Sets the value of the personId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPersonId(String value) {
this.personId = value;
}
}

View file

@ -0,0 +1 @@
package org.keycloak.example.ws.types;

View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Apache ServiceMix Archetype -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<bean id="kcAdapterConfig" class="org.keycloak.representations.adapters.config.AdapterConfig">
<property name="realm" value="demo"/>
<property name="resource" value="custom-cxf-endpoint"/>
<property name="realmKey" value="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB"/>
<property name="bearerOnly" value="true"/>
<property name="sslRequired" value="EXTERNAL"/>
</bean>
<bean id="keycloakAuthenticator" class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
<property name="adapterConfig">
<ref local="kcAdapterConfig" />
</property>
</bean>
<bean id="constraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="Customers"/>
<property name="roles">
<list>
<value>user</value>
</list>
</property>
<property name="authenticate" value="true"/>
<property name="dataConstraint" value="0"/>
</bean>
<bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="constraint"/>
<property name="pathSpec" value="/*"/>
</bean>
<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<property name="authenticator" ref="keycloakAuthenticator" />
<property name="constraintMappings">
<list>
<ref local="constraintMapping" />
</list>
</property>
<property name="authMethod" value="BASIC"/>
<property name="realmName" value="does-not-matter"/>
</bean>
<httpj:engine-factory bus="cxf" id="kc-cxf-endpoint">
<httpj:engine port="8282">
<httpj:handlers>
<ref local="securityHandler" />
</httpj:handlers>
<httpj:sessionSupport>true</httpj:sessionSupport>
</httpj:engine>
</httpj:engine-factory>
<jaxws:endpoint
implementor="org.keycloak.example.ws.PersonImpl"
address="http://localhost:8282/PersonServiceCF" depends-on="kc-cxf-endpoint"/>
</beans>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>keycloak-fuse-example-features</artifactId>
<name>Keycloak Fuse Example - Features</name>
<description/>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>filter</id>
<phase>generate-resources</phase>
<goals>
<goal>resources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>target/classes/features.xml</file>
<type>xml</type>
<classifier>features</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,19 @@
<?xml version='1.0' encoding='UTF-8'?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0" name="keycloak-${project.version}">
<feature name="keycloak-fuse-example" version="${project.version}">
<details>The keycloak fuse example</details>
<feature>war</feature>
<feature>camel</feature>
<feature>camel-jetty</feature>
<feature>cxf</feature>
<feature>keycloak</feature>
<bundle dependency="true">mvn:org.codehaus.jackson/jackson-jaxrs/${jackson.version}</bundle>
<bundle>mvn:org.keycloak.example.demo/product-portal-fuse-example/${project.version}</bundle>
<bundle>mvn:org.keycloak.example.demo/customer-portal-fuse-example/${project.version}/war</bundle>
<bundle>mvn:org.keycloak.example.demo/camel-endpoint-example/${project.version}</bundle>
<bundle>mvn:org.keycloak.example.demo/cxf-jaxws-example/${project.version}</bundle>
<bundle>mvn:org.keycloak.example.demo/cxf-jaxrs-example/${project.version}</bundle>
</feature>
</features>

37
examples/fuse/pom.xml Normal file
View file

@ -0,0 +1,37 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Fuse examples</name>
<description/>
<modelVersion>4.0.0</modelVersion>
<artifactId>fuse-pom</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>customer-app-fuse</module>
<module>product-app-fuse</module>
<module>cxf-jaxrs</module>
<module>cxf-jaxws</module>
<module>camel</module>
<module>features</module>
</modules>
</project>

View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>product-portal-fuse-example</artifactId>
<packaging>bundle</packaging>
<name>Product Portal - Secured in Karaf/Fuse</name>
<description/>
<properties>
<keycloak.osgi.export>
</keycloak.osgi.export>
<keycloak.osgi.import>
org.eclipse.jetty.security;version="[8.1,10)",
org.eclipse.jetty.util.security;version="[8.1,10)",
org.keycloak.adapters.jetty;version="${project.version}",
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
<keycloak.osgi.private>
org.keycloak.example.*
</keycloak.osgi.private>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Dependency for jaxws client to allow sending request to jaxws endpoint provided by cxf-jaxws-example -->
<dependency>
<groupId>org.keycloak.example.demo</groupId>
<artifactId>cxf-jaxws-example</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Private-Package>${keycloak.osgi.private}</Private-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
<Require-Bundle>org.apache.cxf.bundle</Require-Bundle>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,95 @@
package org.keycloak.example;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.WebServiceException;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.message.Message;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.constants.ServiceUrlConstants;
import org.keycloak.example.ws.Person;
import org.keycloak.example.ws.UnknownPersonFault;
import org.keycloak.util.KeycloakUriBuilder;
/**
* Servlet for receiving informations about products from backend JAXWS service. Actually it's about "persons" not "products" :)
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ProductPortalServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
// Send jaxws request
PrintWriter out = resp.getWriter();
out.println("<html><head><title>Product Portal Page</title></head><body>");
String logoutUri = KeycloakUriBuilder.fromUri("http://localhost:8080/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
.queryParam("redirect_uri", "http://localhost:8181/product-portal").build("demo").toString();
String acctUri = KeycloakUriBuilder.fromUri("http://localhost:8080/auth").path(ServiceUrlConstants.ACCOUNT_SERVICE_PATH)
.queryParam("referrer", "product-portal").build("demo").toString();
out.println("<p>Goto: <a href=\"/customer-portal\">customers</a> | <a href=\"" + logoutUri + "\">logout</a> | <a href=\"" + acctUri + "\">manage acct</a></p>");
out.println("Servlet User Principal <b>" + req.getUserPrincipal() + "</b> made this request.");
String unsecuredWsClientResponse = sendWsReq(req, false);
String securedWsClientResponse = sendWsReq(req, true);
out.println("<p>Person with ID 1 - unsecured request: <b>" + unsecuredWsClientResponse + "</b></p>");
out.println("<p>Person with ID 1 - secured request: <b>" + securedWsClientResponse + "</b></p>");
out.println("</body></html>");
out.flush();
out.close();
}
private String sendWsReq(HttpServletRequest req, boolean secured) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(Person.class);
factory.setAddress("http://localhost:8282/PersonServiceCF");
Person simpleClient = (Person)factory.create();
java.lang.String _getPerson_personIdVal = "1";
javax.xml.ws.Holder<java.lang.String> _getPerson_personId = new javax.xml.ws.Holder<java.lang.String>(_getPerson_personIdVal);
javax.xml.ws.Holder<java.lang.String> _getPerson_ssn = new javax.xml.ws.Holder<java.lang.String>();
javax.xml.ws.Holder<java.lang.String> _getPerson_name = new javax.xml.ws.Holder<java.lang.String>();
// Attach Authorization header
if (secured) {
Client clientProxy = ClientProxy.getClient(simpleClient);
KeycloakSecurityContext session = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("Authorization", Arrays.asList("Bearer " + session.getTokenString()));
clientProxy.getRequestContext().put(Message.PROTOCOL_HEADERS, headers);
}
try {
simpleClient.getPerson(_getPerson_personId, _getPerson_ssn, _getPerson_name);
return String.format("Person received: id=%s, name=%s, ssn=%s", _getPerson_personId.value, _getPerson_name.value, _getPerson_ssn.value);
} catch (UnknownPersonFault upf) {
return "UnknownPersonFault has occurred. Details: " + upf.toString();
} catch (WebServiceException wse) {
String error = "Can't receive person. Reason: " + wse.getMessage();
if (wse.getCause() != null) {
Throwable cause = wse.getCause();
error = error + " Details: " + cause.getClass().getName() + ": " + cause.getMessage();
}
return error;
}
}
}

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<!-- USing jetty bean just for the compatibility with other fuse services -->
<bean id="servletConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint">
<bean class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="cst1"/>
<property name="roles">
<list>
<value>user</value>
</list>
</property>
<property name="authenticate" value="true"/>
<property name="dataConstraint" value="0"/>
</bean>
</property>
<property name="pathSpec" value="/product-portal/*"/>
</bean>
<bean id="keycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.PaxWebIntegrationService"
init-method="start" destroy-method="stop">
<property name="jettyWebXmlLocation" value="/WEB-INF/jetty-web.xml" />
<property name="bundleContext" ref="blueprintBundleContext" />
<property name="constraintMappings">
<list>
<ref component-id="servletConstraintMapping" />
</list>
</property>
</bean>
<bean id="productServlet" class="org.keycloak.example.ProductPortalServlet" depends-on="keycloakPaxWebIntegration">
</bean>
<service ref="productServlet" interface="javax.servlet.Servlet">
<service-properties>
<entry key="alias" value="/product-portal" />
<entry key="servlet-name" value="ProductServlet" />
<entry key="keycloak.config.file" value="/keycloak.json" />
</service-properties>
</service>
</blueprint>

View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="securityHandler">
<Set name="authenticator">
<New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
</New>
</Set>
</Get>
</Configure>

View file

@ -0,0 +1,10 @@
{
"realm": "demo",
"resource": "product-portal",
"realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required" : "external",
"credentials": {
"secret": "password"
}
}

View file

@ -0,0 +1,137 @@
{
"realm": "demo",
"enabled": true,
"accessTokenLifespan": 60,
"accessCodeLifespan": 60,
"accessCodeLifespanUserAction": 300,
"ssoSessionIdleTimeout": 600,
"ssoSessionMaxLifespan": 36000,
"passwordCredentialGrantAllowed": true,
"sslRequired": "external",
"registrationAllowed": false,
"social": false,
"updateProfileOnInitialSocialLogin": false,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [ "password" ],
"users" : [
{
"username" : "bburke@redhat.com",
"enabled": true,
"email" : "bburke@redhat.com",
"firstName": "Bill",
"lastName": "Burke",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "stian",
"enabled": true,
"email" : "stian@redhat.com",
"firstName": "Stian",
"lastName": "Thorgersen",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "mposolda@redhat.com",
"enabled": true,
"email" : "mposolda@redhat.com",
"firstName": "Marek",
"lastName": "Posolda",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "admin",
"enabled": true,
"email" : "admin@admin.com",
"firstName": "Admin",
"lastName": "Burke",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user","admin" ],
"applicationRoles": {
"realm-management": [ "realm-admin" ]
}
}
],
"roles" : {
"realm" : [
{
"name": "user",
"description": "User privileges"
},
{
"name": "admin",
"description": "Administrator privileges"
}
]
},
"applications": [
{
"name": "customer-portal",
"enabled": true,
"adminUrl": "http://localhost:8181/customer-portal",
"baseUrl": "http://localhost:8181/customer-portal",
"redirectUris": [
"http://localhost:8181/customer-portal/*"
],
"secret": "password"
},
{
"name": "product-portal",
"enabled": true,
"adminUrl": "http://localhost:8181/product-portal",
"baseUrl": "http://localhost:8181/product-portal",
"redirectUris": [
"http://localhost:8181/product-portal/*"
],
"secret": "password"
},
{
"name": "builtin-cxf-app",
"enabled": true,
"adminUrl": "http://localhost:8181/cxf",
"baseUrl": "http://localhost:8181/cxf",
"redirectUris": [
"http://localhost:8181/cxf/*"
],
"secret": "password"
},
{
"name": "custom-cxf-endpoint",
"enabled": true,
"adminUrl": "http://localhost:8282/PersonServiceCF",
"baseUrl": "http://localhost:8282/PersonServiceCF",
"bearerOnly": true
},
{
"name": "admin-camel-endpoint",
"enabled": true,
"adminUrl": "http://localhost:8383/admin-camel-endpoint",
"baseUrl": "http://localhost:8383/admin-camel-endpoint",
"bearerOnly": true
}
]
}

View file

@ -32,5 +32,6 @@
<module>js-console</module> <module>js-console</module>
<module>multi-tenant</module> <module>multi-tenant</module>
<module>basic-auth</module> <module>basic-auth</module>
<module>fuse</module>
</modules> </modules>
</project> </project>

View file

@ -13,6 +13,17 @@
<name>Keycloak Adapter Core</name> <name>Keycloak Adapter Core</name>
<description/> <description/>
<properties>
<keycloak.osgi.export>
org.keycloak.adapters.*
</keycloak.osgi.export>
<keycloak.osgi.import>
org.keycloak.*;version="${project.version}",
org.apache.http.*;version=${keycloak.apache.httpcomponents.version},
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.bouncycastle</groupId> <groupId>org.bouncycastle</groupId>
@ -73,6 +84,39 @@
<target>${maven.compiler.target}</target> <target>${maven.compiler.target}</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View file

@ -74,7 +74,6 @@
<dependency> <dependency>
<groupId>org.osgi</groupId> <groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId> <artifactId>org.osgi.core</artifactId>
<version>4.3.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View file

@ -13,6 +13,15 @@
<name>Keycloak Jetty Core Integration</name> <name>Keycloak Jetty Core Integration</name>
<properties> <properties>
<jetty9.version>8.1.16.v20140903</jetty9.version> <jetty9.version>8.1.16.v20140903</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.jetty.core.*
</keycloak.osgi.export>
<keycloak.osgi.import>
org.eclipse.jetty.*;version="[8.1,10)";resolution:=optional,
javax.servlet.*;version="[2.5,4)";resolution:=optional,
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
</properties> </properties>
<description /> <description />
@ -94,6 +103,39 @@
<target>1.6</target> <target>1.6</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View file

@ -1,8 +1,6 @@
package org.keycloak.adapters.jetty; package org.keycloak.adapters.jetty.core;
import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.MultiMap;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext; import org.keycloak.KeycloakSecurityContext;
@ -12,7 +10,6 @@ import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext; import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator; import org.keycloak.adapters.RequestAuthenticator;
import org.keycloak.util.MultivaluedHashMap;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;

View file

@ -1,6 +1,5 @@
package org.keycloak.adapters.jetty; package org.keycloak.adapters.jetty.core;
import org.apache.http.HttpVersion;
import org.eclipse.jetty.security.DefaultUserIdentity; import org.eclipse.jetty.security.DefaultUserIdentity;
import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.ServerAuthException;
import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserAuthentication;
@ -162,8 +161,19 @@ public abstract class AbstractKeycloakJettyAuthenticator extends LoginAuthentica
@SuppressWarnings("UseSpecificCatch") @SuppressWarnings("UseSpecificCatch")
public void initializeKeycloak() { public void initializeKeycloak() {
nodesRegistrationManagement = new NodesRegistrationManagement(); nodesRegistrationManagement = new NodesRegistrationManagement();
String contextPath = ContextHandler.getCurrentContext().getContextPath();
ServletContext theServletContext = ContextHandler.getCurrentContext().getContext(contextPath); ServletContext theServletContext = null;
ContextHandler.Context currentContext = ContextHandler.getCurrentContext();
if (currentContext != null) {
String contextPath = currentContext.getContextPath();
if ("".equals(contextPath)) {
// This could be the case in osgi environment when deploying apps through pax whiteboard extension.
theServletContext = currentContext;
} else {
theServletContext = currentContext.getContext(contextPath);
}
}
// Jetty 9.1.x servlet context will be null :( // Jetty 9.1.x servlet context will be null :(
if (configResolver == null && theServletContext != null) { if (configResolver == null && theServletContext != null) {

View file

@ -1,4 +1,4 @@
package org.keycloak.adapters.jetty; package org.keycloak.adapters.jetty.core;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;

View file

@ -1,4 +1,4 @@
package org.keycloak.adapters.jetty; package org.keycloak.adapters.jetty.core;
import org.keycloak.KeycloakSecurityContext; import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.HttpFacade; import org.keycloak.adapters.HttpFacade;

View file

@ -1,4 +1,4 @@
package org.keycloak.adapters.jetty; package org.keycloak.adapters.jetty.core;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;

View file

@ -1,4 +1,4 @@
package org.keycloak.adapters.jetty; package org.keycloak.adapters.jetty.core;
import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.server.SessionManager;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;

View file

@ -0,0 +1,30 @@
package org.keycloak.adapters.jetty.core;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.session.SessionHandler;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class WrappingSessionHandler extends SessionHandler {
public WrappingSessionHandler() {
super();
}
public WrappingSessionHandler(SessionManager mgr) {
super(mgr);
}
@Override
public void setHandler(Handler handler) {
if (getHandler() != null && getHandler() instanceof HandlerWrapper) {
HandlerWrapper wrappedHandler = (HandlerWrapper) getHandler();
wrappedHandler.setHandler(handler);
} else {
super.setHandler(handler);
}
}
}

View file

@ -13,6 +13,14 @@
<name>Keycloak Jetty 8.1.x Integration</name> <name>Keycloak Jetty 8.1.x Integration</name>
<properties> <properties>
<jetty9.version>8.1.16.v20140903</jetty9.version> <jetty9.version>8.1.16.v20140903</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.jetty.*
</keycloak.osgi.export>
<keycloak.osgi.import>
javax.servlet.*;version="[2.5,4)";resolution:=optional,
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
</properties> </properties>
<description /> <description />
@ -99,6 +107,39 @@
<target>1.6</target> <target>1.6</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View file

@ -4,6 +4,7 @@ import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.MultiMap;
import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.jetty.core.AbstractJettySessionTokenStore;
import org.keycloak.util.MultivaluedHashMap; import org.keycloak.util.MultivaluedHashMap;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;

View file

@ -6,6 +6,7 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.UserIdentity;
import org.keycloak.adapters.AdapterTokenStore; import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.jetty.core.AbstractKeycloakJettyAuthenticator;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;

View file

@ -13,6 +13,15 @@
<name>Keycloak Jetty 9.1.x Integration</name> <name>Keycloak Jetty 9.1.x Integration</name>
<properties> <properties>
<jetty9.version>9.1.5.v20140505</jetty9.version> <jetty9.version>9.1.5.v20140505</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.jetty.*
</keycloak.osgi.export>
<keycloak.osgi.import>
org.eclipse.jetty.*;version="[9.1,9.2)";resolution:=optional,
javax.servlet.*;version="[3.0,4)";resolution:=optional,
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
</properties> </properties>
<description /> <description />
@ -113,6 +122,39 @@
<target>1.6</target> <target>1.6</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View file

@ -5,6 +5,7 @@ import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.MultiMap;
import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.jetty.core.AbstractJettySessionTokenStore;
import org.keycloak.util.MultivaluedHashMap; import org.keycloak.util.MultivaluedHashMap;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;

View file

@ -6,6 +6,7 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.UserIdentity;
import org.keycloak.adapters.AdapterTokenStore; import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.jetty.core.AbstractKeycloakJettyAuthenticator;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;

View file

@ -13,6 +13,15 @@
<name>Keycloak Jetty 9.2.x Integration</name> <name>Keycloak Jetty 9.2.x Integration</name>
<properties> <properties>
<jetty9.version>9.2.4.v20141103</jetty9.version> <jetty9.version>9.2.4.v20141103</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.jetty.*
</keycloak.osgi.export>
<keycloak.osgi.import>
org.eclipse.jetty.*;resolution:=optional,
javax.servlet.*;version="[3.0,4)";resolution:=optional,
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
</properties> </properties>
<description /> <description />
@ -99,6 +108,39 @@
<target>1.6</target> <target>1.6</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View file

@ -5,10 +5,10 @@ import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.MultiMap;
import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.jetty.core.AbstractJettySessionTokenStore;
import org.keycloak.util.MultivaluedHashMap; import org.keycloak.util.MultivaluedHashMap;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import java.lang.reflect.Field;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>

View file

@ -6,6 +6,7 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.UserIdentity;
import org.keycloak.adapters.AdapterTokenStore; import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.jetty.core.AbstractKeycloakJettyAuthenticator;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;

View file

@ -0,0 +1,104 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-osgi-adapter</artifactId>
<name>Keycloak OSGI Adapter</name>
<packaging>jar</packaging>
<properties>
<jetty9.version>8.1.16.v20140903</jetty9.version>
<keycloak.osgi.export>
org.keycloak.adapters.osgi.*
</keycloak.osgi.export>
<keycloak.osgi.import>
org.ops4j.pax.web.*;version="[3.0,4)",
javax.servlet.*;version="[2.5,4)";resolution:=optional,
org.eclipse.jetty.*;version="[8.1,10)";resolution:=optional,
org.keycloak.*;version="${project.version}",
*;resolution:=optional
</keycloak.osgi.import>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.enterprise</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.web</groupId>
<artifactId>pax-web-runtime</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>${jetty9.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>${keycloak.osgi.import}</Import-Package>
<Export-Package>${keycloak.osgi.export}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,163 @@
package org.keycloak.adapters.osgi;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.util.security.Constraint;
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.http.HttpContext;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* Integration with pax-web, which allows to inject custom jetty-web.xml configuration from current bundle classpath into {@link WebContainer}
* and allows to inject custom security constraint for securing resources by Keycloak.
*
* <p>It assumes that pax-web {@link WebContainer} is used as implementation of OSGI {@link org.osgi.service.http.HttpService}, which
* is true in karaf/fuse environment</p>
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class PaxWebIntegrationService {
protected static final Logger log = Logger.getLogger(PaxWebIntegrationService.class);
private BundleContext bundleContext;
private String jettyWebXmlLocation;
private List<ConstraintMapping> constraintMappings; // Using jetty constraint mapping just because of compatibility with other fuse services
private ServiceTracker webContainerTracker;
private HttpContext httpContext;
public BundleContext getBundleContext() {
return bundleContext;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public String getJettyWebXmlLocation() {
return jettyWebXmlLocation;
}
public void setJettyWebXmlLocation(String jettyWebXmlLocation) {
this.jettyWebXmlLocation = jettyWebXmlLocation;
}
public List<ConstraintMapping> getConstraintMappings() {
return constraintMappings;
}
public void setConstraintMappings(List<ConstraintMapping> constraintMappings) {
this.constraintMappings = constraintMappings;
}
protected ServiceTracker getWebContainerTracker() {
return webContainerTracker;
}
protected HttpContext getHttpContext() {
return httpContext;
}
public void start() {
ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() {
@Override
public Object addingService(ServiceReference reference) {
return addingWebContainerCallback(reference);
}
@Override
public void modifiedService(ServiceReference reference, Object service) {
}
@Override
public void removedService(ServiceReference reference, Object service) {
removingWebContainerCallback(reference);
}
};
webContainerTracker = new ServiceTracker(bundleContext, WebContainer.class.getName(), trackerCustomizer);
webContainerTracker.open();
}
public void stop() {
webContainerTracker.remove(webContainerTracker.getServiceReference());
}
protected WebContainer addingWebContainerCallback(ServiceReference webContainerServiceReference) {
WebContainer service = (WebContainer) bundleContext.getService(webContainerServiceReference);
httpContext = service.createDefaultHttpContext();
addJettyWebXml(service);
if (constraintMappings == null) {
throw new IllegalStateException("constraintMappings was null!");
}
for (ConstraintMapping constraintMapping : constraintMappings) {
addConstraintMapping(service, constraintMapping);
}
service.registerLoginConfig("BASIC", "does-not-matter", null, null, httpContext);
return service;
}
protected void addJettyWebXml(WebContainer service) {
String jettyWebXmlLoc;
if (this.jettyWebXmlLocation == null) {
jettyWebXmlLoc = "/WEB-INF/jetty-web.xml";
} else {
jettyWebXmlLoc = this.jettyWebXmlLocation;
}
URL jettyWebXml = bundleContext.getBundle().getResource(jettyWebXmlLoc);
if (jettyWebXml != null) {
log.debug("Found jetty-web XML configuration on bundle classpath on " + jettyWebXmlLoc);
service.registerJettyWebXml(jettyWebXml, httpContext);
} else {
log.debug("Not found jetty-web XML configuration on bundle classpath on " + jettyWebXmlLoc);
}
}
protected void addConstraintMapping(WebContainer service, ConstraintMapping constraintMapping) {
Constraint constraint = constraintMapping.getConstraint();
String[] roles = constraint.getRoles();
// name property is unavailable on constraint object :/
String name = "Constraint-" + new Random().nextInt();
int dataConstraint = constraint.getDataConstraint();
String dataConstraintStr;
switch (dataConstraint) {
case Constraint.DC_UNSET: dataConstraintStr = null; break;
case Constraint.DC_NONE: dataConstraintStr = "NONE"; break;
case Constraint.DC_CONFIDENTIAL: dataConstraintStr = "CONFIDENTIAL"; break;
case Constraint.DC_INTEGRAL: dataConstraintStr = "INTEGRAL"; break;
default:
log.warnv("Unknown data constraint: " + dataConstraint);
dataConstraintStr = "CONFIDENTIAL";
}
List<String> rolesList = Arrays.asList(roles);
log.debug("Adding security constraint name=" + name + ", url=" + constraintMapping.getPathSpec() + ", dataConstraint=" + dataConstraintStr + ", canAuthenticate="
+ constraint.getAuthenticate() + ", roles=" + rolesList);
service.registerConstraintMapping(name, constraintMapping.getPathSpec(), null, dataConstraintStr, constraint.getAuthenticate(), rolesList, httpContext);
}
protected void removingWebContainerCallback(ServiceReference serviceReference) {
WebContainer service = (WebContainer)bundleContext.getService(serviceReference);
if (service != null) {
service.unregisterLoginConfig(httpContext);
service.unregisterConstraintMapping(httpContext);
}
}
}

View file

@ -0,0 +1,100 @@
package org.keycloak.adapters.osgi;
import java.util.Hashtable;
import javax.servlet.Servlet;
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.http.HttpContext;
/**
* Service, which allows to remove previously registered servlets in karaf/fuse environment. It assumes that particular servlet was previously
* registered as service in OSGI container under {@link javax.servlet.Servlet} interface.
*
* <p>The point is to register automatically registered builtin servlet endpoints (like "/cxf" for instance) to allow secure them
* by Keycloak and re-register them again</p>
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ServletUnregistrationService {
protected static final Logger log = Logger.getLogger(ServletUnregistrationService.class);
private BundleContext bundleContext;
private ServiceReference servletReference;
public BundleContext getBundleContext() {
return bundleContext;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public ServiceReference getServletReference() {
return servletReference;
}
public void setServletReference(ServiceReference servletReference) {
this.servletReference = servletReference;
}
// TODO: Re-register original servlet back during stop?
public void start() {
if (servletReference == null) {
throw new IllegalStateException("No servlet reference provided");
}
Servlet servlet = (Servlet) bundleContext.getService(servletReference);
WebContainer webContainer = findWebContainer(servletReference);
if (webContainer == null) {
return;
}
// Unregister servlet now
try {
webContainer.unregisterServlet(servlet);
log.debugv("Original servlet with alias " + servletReference.getProperty("alias") + " unregistered successfully.");
} catch (IllegalStateException e) {
log.warnv("Can't unregister servlet due to: " + e.getMessage());
}
}
public void stop() {
try {
Servlet servlet = (Servlet) bundleContext.getService(servletReference);
WebContainer webContainer = findWebContainer(servletReference);
if (webContainer == null) {
return;
}
Hashtable<String, Object> servletInitParams = new Hashtable<String, Object>();
String[] propNames = servletReference.getPropertyKeys();
for (String propName : propNames) {
servletInitParams.put(propName, servletReference.getProperty(propName));
}
// Try to register original servlet back
HttpContext httpContext = webContainer.createDefaultHttpContext();
String alias = (String) servletReference.getProperty("alias");
webContainer.registerServlet(alias, servlet, servletInitParams, httpContext);
} catch (Exception e) {
log.warn("Can't register original servlet back", e);
}
}
protected WebContainer findWebContainer(ServiceReference servletRef) {
BundleContext servletBundleContext = servletRef.getBundle().getBundleContext();
ServiceReference webContainerReference = servletBundleContext.getServiceReference(WebContainer.class.getName());
if (webContainerReference == null) {
log.warn("Not found webContainer reference for bundle " + servletBundleContext);
return null;
} else {
return (WebContainer) servletBundleContext.getService(webContainerReference);
}
}
}

View file

@ -28,5 +28,6 @@
<module>js</module> <module>js</module>
<module>installed</module> <module>installed</module>
<module>admin-client</module> <module>admin-client</module>
<module>osgi-adapter</module>
</modules> </modules>
</project> </project>

20
pom.xml
View file

@ -13,6 +13,7 @@
<properties> <properties>
<aesh.version>0.33.12</aesh.version> <aesh.version>0.33.12</aesh.version>
<base64.version>2.3.8</base64.version>
<bouncycastle.version>1.46</bouncycastle.version> <bouncycastle.version>1.46</bouncycastle.version>
<jackson.version>1.9.9</jackson.version> <jackson.version>1.9.9</jackson.version>
<keycloak.apache.httpcomponents.version>4.2.1</keycloak.apache.httpcomponents.version> <keycloak.apache.httpcomponents.version>4.2.1</keycloak.apache.httpcomponents.version>
@ -48,6 +49,8 @@
<infinispan.version>6.0.2.Final</infinispan.version> <infinispan.version>6.0.2.Final</infinispan.version>
<liquibase.version>3.2.2</liquibase.version> <liquibase.version>3.2.2</liquibase.version>
<jetty9.version>9.1.0.v20131115</jetty9.version> <jetty9.version>9.1.0.v20131115</jetty9.version>
<osgi.version>4.2.0</osgi.version>
<pax.web.version>3.1.2</pax.web.version>
<!-- maven-compiler-plugin --> <!-- maven-compiler-plugin -->
<maven.compiler.target>1.6</maven.compiler.target> <maven.compiler.target>1.6</maven.compiler.target>
@ -139,7 +142,7 @@
<dependency> <dependency>
<groupId>net.iharder</groupId> <groupId>net.iharder</groupId>
<artifactId>base64</artifactId> <artifactId>base64</artifactId>
<version>2.3.8</version> <version>${base64.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.mail</groupId> <groupId>javax.mail</groupId>
@ -508,6 +511,21 @@
<artifactId>liquibase-core</artifactId> <artifactId>liquibase-core</artifactId>
<version>${liquibase.version}</version> <version>${liquibase.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.enterprise</artifactId>
<version>${osgi.version}</version>
</dependency>
<dependency>
<groupId>org.ops4j.pax.web</groupId>
<artifactId>pax-web-runtime</artifactId>
<version>${pax.web.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

View file

@ -316,8 +316,8 @@ public class JaxrsFilterTest {
// @Test // @Test
public void testCxfExample() { public void testCxfExample() {
String uri = "http://localhost:9000/customerservice/customers/123"; //String uri = "http://localhost:9000/customerservice/customers/123";
//String uri = "http://localhost:8080/jax_rs_basic_servlet/services/service1/customerservice/customers/123"; String uri = "http://localhost:8080/jax_rs_basic_servlet/services/service1/customerservice/customers/123";
Response resp = client.target(uri).request() Response resp = client.target(uri).request()
.get(); .get();
Assert.assertEquals(resp.getStatus(), 401); Assert.assertEquals(resp.getStatus(), 401);

View file

@ -21,49 +21,23 @@
*/ */
package org.keycloak.testsuite; package org.keycloak.testsuite;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.jetty.AbstractKeycloakJettyAuthenticator;
import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OpenIDConnectService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.adapter.AdapterTestStrategy; import org.keycloak.testsuite.adapter.AdapterTestStrategy;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule; import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testutils.KeycloakServer;
import org.openqa.selenium.WebDriver;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.UriBuilder;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import java.security.Principal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View file

@ -21,49 +21,23 @@
*/ */
package org.keycloak.testsuite; package org.keycloak.testsuite;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.jetty.AbstractKeycloakJettyAuthenticator;
import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OpenIDConnectService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.adapter.AdapterTestStrategy; import org.keycloak.testsuite.adapter.AdapterTestStrategy;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule; import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testutils.KeycloakServer;
import org.openqa.selenium.WebDriver;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.UriBuilder;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import java.security.Principal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;