Merge pull request #10 from mposolda/master
More Fuse adapter documentation. Remove references to Apache Karaf
This commit is contained in:
commit
faaf1460b1
8 changed files with 568 additions and 87 deletions
|
@ -10,7 +10,13 @@
|
|||
.. link:topics/oidc/java/java-adapters.adoc[Java Adapters]
|
||||
... link:topics/oidc/java/java-adapter-config.adoc[Java Adapters Config]
|
||||
... link:topics/oidc/java/jboss-adapter.adoc[JBoss EAP/Wildfly Adapter]
|
||||
... link:topics/oidc/java/fuse-adapter.adoc[JBoss Fuse and Apache Karaf Adapter]
|
||||
... link:topics/oidc/java/fuse-adapter.adoc[JBoss Fuse Adapter]
|
||||
.... link:topics/oidc/java/fuse/classic-war.adoc[Classic WAR application]
|
||||
.... link:topics/oidc/java/fuse/servlet-whiteboard.adoc[Servlet Deployed as OSGI Service]
|
||||
.... link:topics/oidc/java/fuse/camel.adoc[Apache Camel]
|
||||
.... link:topics/oidc/java/fuse/cxf-separate.adoc[Apache CXF on Separate Jetty]
|
||||
.... link:topics/oidc/java/fuse/cxf-builtin.adoc[Apache CXF on default Jetty]
|
||||
.... link:topics/oidc/java/fuse/fuse-admin.adoc[Fuse Admin Services]
|
||||
{% if book.community %}
|
||||
... link:topics/oidc/java/tomcat-adapter.adoc[Tomcat 6, 7 and 8 Adapters]
|
||||
... link:topics/oidc/java/jetty9-adapter.adoc[Jetty 9.x Adapters]
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
|
||||
[[_fuse_adapter]]
|
||||
=== JBoss Fuse and Apache Karaf Adapter
|
||||
=== JBoss Fuse Adapter
|
||||
|
||||
NOTE: JBoss Fuse is a Technology Preview feature and is not fully supported
|
||||
|
||||
Currently Keycloak supports securing your web applications running inside http://www.jboss.org/products/fuse/overview/[JBoss Fuse] or http://karaf.apache.org/[Apache Karaf] .
|
||||
It leverages <<_jetty8_adapter,Jetty 8 adapter>> as both JBoss Fuse 6.2 and Apache Karaf 3 are bundled with http://eclipse.org/jetty/[Jetty 8.1 server]
|
||||
Currently {{book.project.name}} supports securing your web applications running inside http://www.jboss.org/products/fuse/overview/[JBoss Fuse] .
|
||||
It leverages <<fake/../jetty8-adapter.adoc#_jetty8_adapter,Jetty 8 adapter>> as both JBoss Fuse 6.2 are bundled with http://eclipse.org/jetty/[Jetty 8.1 server]
|
||||
under the covers and Jetty is used for running various kinds of web applications.
|
||||
|
||||
What is supported for Fuse/Karaf is:
|
||||
What is supported for Fuse is:
|
||||
|
||||
* Security for classic WAR applications deployed on Fuse/Karaf with https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+War[Pax Web War Extender].
|
||||
* Security for servlets deployed on Fuse/Karaf as OSGI services with https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+Whiteboard[Pax Web Whiteboard Extender].
|
||||
* Security for classic WAR applications deployed on Fuse with https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+War[Pax Web War Extender].
|
||||
* Security for servlets deployed on Fuse as OSGI services with https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+Whiteboard[Pax Web Whiteboard Extender].
|
||||
* Security for http://camel.apache.org/[Apache Camel] Jetty endpoints running with http://camel.apache.org/jetty.html[Camel Jetty] component.
|
||||
* Security for http://cxf.apache.org/[Apache CXF] endpoints running on their own separate http://cxf.apache.org/docs/jetty-configuration.html[Jetty engine].
|
||||
* Security for http://cxf.apache.org/[Apache CXF] endpoints running on default engine provided by CXF servlet.
|
||||
|
@ -19,84 +19,10 @@ What is supported for Fuse/Karaf is:
|
|||
|
||||
==== How to secure your web applications inside Fuse
|
||||
|
||||
The best place to start is look at Fuse demo bundled as part of Keycloak examples in directory `fuse` . Most of the steps should be understandable from testing and
|
||||
Basically all mentioned web applications require to inject {{book.project.name}} Jetty authenticator into underlying Jetty server . The steps to achieve it are bit different
|
||||
according to application type. The details are described in individual sub-chapters.
|
||||
|
||||
{% if book.community %}
|
||||
The best place to start is look at Fuse demo bundled as part of {{book.project.name}} examples in directory `fuse` . Most of the steps should be understandable from testing and
|
||||
understanding the demo.
|
||||
|
||||
Basically all mentioned web applications require to inject Keycloak Jetty authenticator into underlying Jetty server . The steps to achieve it are bit different
|
||||
according to application type.
|
||||
|
||||
|
||||
===== Classic WAR application
|
||||
|
||||
The needed steps are:
|
||||
|
||||
* Declare needed constraints in `/WEB-INF/web.xml`
|
||||
* Add `jetty-web.xml` file with the authenticator to `/WEB-INF/jetty-web.xml` and add `/WEB-INF/keycloak.json` with your Keycloak configuration
|
||||
* Make sure your WAR imports `org.keycloak.adapters.jetty` and maybe some more packages in MANIFEST.MF file in header `Import-Package`. It's
|
||||
recommended to use maven-bundle-plugin similarly like Fuse examples are doing, but note that "*" resolution for package doesn't import `org.keycloak.adapters.jetty` package
|
||||
as it's not used by application or Blueprint or Spring descriptor, but it's used just in jetty-web.xml file.
|
||||
|
||||
Take a look at `customer-portal-app` from fuse example for inspiration.
|
||||
|
||||
===== Servlet web application deployed by pax-whiteboard-extender
|
||||
|
||||
The needed steps are:
|
||||
|
||||
* Keycloak provides PaxWebIntegrationService, which allows to inject jetty-web.xml and configure security constraints for your application.
|
||||
Example `product-portal-app` declares this in `OSGI-INF/blueprint/blueprint.xml` . Note that your servlet needs to depend on it.
|
||||
* Steps 2,3 are same like for classic WAR
|
||||
|
||||
Take a look at `product-portal-app` for inspiration.
|
||||
|
||||
===== Apache camel application
|
||||
|
||||
You can secure your Apache camel endpoint using http://camel.apache.org/jetty.html[camel-jetty] endpoint by adding securityHandler with `KeycloakJettyAuthenticator` and
|
||||
proper security constraints injected. Take a look at `OSGI-INF/blueprint/blueprint.xml` configuration in `camel` application on example of how it can be done in details.
|
||||
|
||||
===== Apache CXF endpoint
|
||||
|
||||
It's recommended to run your CXF endpoints secured by Keycloak on separate Jetty engine. You need to add `META-INF/spring/beans.xml` to your application
|
||||
and then declare `httpj:engine-factory` with Jetty SecurityHandler with injected `KeycloakJettyAuthenticator` inside.
|
||||
|
||||
Fore more details, take a look at example application `cxf-ws` from Keycloak Fuse demo, which is using separate endpoint on
|
||||
http://localhost:8282 . All the important configuration inside this application is declared in `META-INF/spring/beans.xml` .
|
||||
|
||||
===== Builtin CXF web applications
|
||||
|
||||
Some services automatically come with deployed servlets on startup. One of such examples is CXF servlet running on
|
||||
http://localhost:8181/cxf context. Securing such endpoints is quite tricky. The approach, which Keycloak is currently using,
|
||||
is providing ServletReregistrationService, which undeploys builtin servlet at startup, so you are able to re-deploy it again on context secured by Keycloak.
|
||||
You can see the `OSGI-INF/blueprint/blueprint.xml` inside `cxf-jaxrs` example, which adds JAX-RS `customerservice` endpoint and more importantly, it secures whole `/cxf` context.
|
||||
|
||||
As a side effect, all other CXF services running on default CXF HTTP destination will be secured too. Once you uninstall feature `keycloak-fuse-6.2-example`, the
|
||||
original unsecured servlet on `/cxf` context is deployed back and hence context will become unsecured again.
|
||||
|
||||
It's recommended to use your own Jetty engine for your apps (similarly like `cxf-jaxws` application is doing).
|
||||
|
||||
|
||||
==== How to secure Fuse admin services
|
||||
|
||||
===== SSH authentication to Fuse terminal with Keycloak credentials
|
||||
|
||||
Keycloak mainly addresses usecases for authentication of web applications, however if your admin services (like fuse admin console) are protected
|
||||
with Keycloak, it may be good to protect non-web services like SSH with Keycloak credentials too. It's possible to do it by using JAAS login module, which
|
||||
allows to remotely connect to Keycloak and verify credentials based on <<_direct_access_grants,Direct Access Grants>> .
|
||||
|
||||
Example steps for enable SSH authentication require changing the configuration of `sshRealm` in `$FUSE_HOME/etc/org.apache.karaf.shell.cfg`, then adding
|
||||
file `$FUSE_HOME/etc/keycloak-direct-access.json` (this is default location, which can be changed) and install the needed feature `keycloak-jaas`. It's described in details
|
||||
in the README file of Fuse example, which in example distribution is inside `fuse/fuse-admin/README.md` .
|
||||
|
||||
|
||||
===== JMX authentication with Keycloak credentials
|
||||
|
||||
This may be needed in case if you really want to use jconsole or other external tool to perform remote connection to JMX through RMI. Otherwise it may
|
||||
be better to use just hawt.io/jolokia as jolokia agent is installed in http://hawt.io by default.
|
||||
|
||||
You need to configure `jmxRealm` in `$FUSE_HOME/etc/org.apache.karaf.management.cfg`, then adding file `$FUSE_HOME/etc/keycloak-direct-access.json`
|
||||
(this is default location, which can be changed) and install the needed feature `keycloak-jaas`.
|
||||
It's described in details in the README file of Fuse example, which in example distribution is inside `fuse/fuse-admin/README.md` .
|
||||
|
||||
|
||||
===== Secure Fuse admin console
|
||||
|
||||
Fuse admin console is Hawt.io. See http://hawt.io/configuration/index.html[Hawt.io documentation] for more info about how to secure it with Keycloak.
|
||||
{% endif %}
|
95
topics/oidc/java/fuse/camel.adoc
Normal file
95
topics/oidc/java/fuse/camel.adoc
Normal file
|
@ -0,0 +1,95 @@
|
|||
|
||||
[[_fuse_adapter_camel]]
|
||||
==== Apache Camel Application
|
||||
|
||||
* You can secure your Apache camel endpoint using http://camel.apache.org/jetty.html[camel-jetty] component by adding securityHandler with `KeycloakJettyAuthenticator` and
|
||||
proper security constraints injected. You can add file `OSGI-INF/blueprint/blueprint.xml` into your camel application with the configuration similar to below.
|
||||
The roles, security constraint mappings and {{book.project.name}} adapter configuration may be a bit different according to your environment and needs:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<?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="MIGfMA0G..."/>
|
||||
<property name="bearerOnly" value="true"/>
|
||||
<property name="authServerUrl" value="http://localhost:8080/auth" />
|
||||
<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.spi.WrappingSessionHandler">
|
||||
<property name="handler" ref="securityHandler" />
|
||||
</bean>
|
||||
|
||||
<bean id="helloProcessor" class="org.keycloak.example.CamelHelloProcessor" />
|
||||
|
||||
<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&matchOnUriPrefix=true" />
|
||||
<process ref="helloProcessor" />
|
||||
<log message="The message from camel endpoint contains ${body}"/>
|
||||
</route>
|
||||
</camelContext>
|
||||
|
||||
</blueprint>
|
||||
----
|
||||
|
||||
|
||||
* The `Import-Package` in `META-INF/MANIFEST.MF` needs to contain those imports:
|
||||
[source]
|
||||
----
|
||||
javax.servlet;version="[3,4)",
|
||||
javax.servlet.http;version="[3,4)",
|
||||
org.apache.camel.*,
|
||||
org.apache.camel;version="[2.13,3)",
|
||||
org.eclipse.jetty.security;version="[8,10)",
|
||||
org.eclipse.jetty.server.nio;version="[8,10)",
|
||||
org.eclipse.jetty.util.security;version="[8,10)",
|
||||
org.keycloak.*;version="{{book.project.version}}",
|
||||
org.osgi.service.blueprint,
|
||||
org.osgi.service.blueprint.container,
|
||||
org.osgi.service.event,
|
||||
----
|
||||
|
82
topics/oidc/java/fuse/classic-war.adoc
Normal file
82
topics/oidc/java/fuse/classic-war.adoc
Normal file
|
@ -0,0 +1,82 @@
|
|||
|
||||
[[_fuse_adapter_classic_war]]
|
||||
==== Secure Classic WAR application
|
||||
|
||||
The needed steps to secure your WAR are:
|
||||
|
||||
* Declare needed security constraints in `/WEB-INF/web.xml` . You also need to declare login-config and all the roles inside security-role.
|
||||
The example configuration can look like this:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<?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>
|
||||
----
|
||||
|
||||
* Add `jetty-web.xml` file with the authenticator to `/WEB-INF/jetty-web.xml` . Typically it will look like this:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<?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>
|
||||
----
|
||||
|
||||
* Add `/WEB-INF/keycloak.json` with your {{book.project.name}} configuration. The format of this config file is described
|
||||
in the <<fake/../../java-adapter-config.adoc#_java_adapter_config,Java Adapters Config>> section.
|
||||
|
||||
* Make sure your WAR imports `org.keycloak.adapters.jetty` and maybe some more packages in `META-INF/MANIFEST.MF` file in header `Import-Package`. It's
|
||||
recommended to use `maven-bundle-plugin` in your project to properly generate OSGI headers in manifest.
|
||||
Note that "*" resolution for package doesn't import `org.keycloak.adapters.jetty` package
|
||||
as it's not used by application or Blueprint or Spring descriptor, but it's used just in `jetty-web.xml` file. So list of the packages to import may look like this:
|
||||
|
||||
[source]
|
||||
----
|
||||
org.keycloak.adapters.jetty;version="{{book.project.version}}",
|
||||
org.keycloak.adapters;version="{{book.project.version}}",
|
||||
org.keycloak.constants;version="{{book.project.version}}",
|
||||
org.keycloak.util;version="{{book.project.version}}",
|
||||
org.keycloak.*;version="{{book.project.version}}",
|
||||
*;resolution:=optional
|
||||
----
|
||||
|
98
topics/oidc/java/fuse/cxf-builtin.adoc
Normal file
98
topics/oidc/java/fuse/cxf-builtin.adoc
Normal file
|
@ -0,0 +1,98 @@
|
|||
|
||||
[[_fuse_adapter_cxf_builtin]]
|
||||
==== Secure Apache CXF Endpoint on default Jetty Engine
|
||||
|
||||
Some services automatically come with deployed servlets on startup. One of such services is CXF servlet running on
|
||||
http://localhost:8181/cxf context. Securing such endpoints is quite tricky. The approach, which {{book.project.name}} is currently using,
|
||||
is providing ServletReregistrationService, which undeploys builtin servlet at startup, so you are able to re-deploy it again on context secured by {{book.project.name}}.
|
||||
This is how configuration file `OSGI-INF/blueprint/blueprint.xml` inside your application may look like. Note it adds JAX-RS `customerservice` endpoint,
|
||||
which is endpoint specific to your application, but more importantly, it secures whole `/cxf` context.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<?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"
|
||||
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/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.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" />
|
||||
</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 -->
|
||||
|
||||
<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="defaultCxfReregistration" class="org.keycloak.adapters.osgi.ServletReregistrationService" depends-on="cxfKeycloakPaxWebIntegration"
|
||||
init-method="start" destroy-method="stop">
|
||||
<property name="bundleContext" ref="blueprintBundleContext" />
|
||||
<property name="managedServiceReference">
|
||||
<reference interface="org.osgi.service.cm.ManagedService" filter="(service.pid=org.apache.cxf.osgi)" timeout="5000" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</blueprint>
|
||||
----
|
||||
|
||||
As a side effect, all other CXF services running on default CXF HTTP destination will be secured too. Similarly when the application is undeployed, then
|
||||
whole `/cxf` context will become unsecured too. For this reason, it's recommended to use your own Jetty engine for your apps like
|
||||
described in <<fake/../cxf-separate.adoc#_fuse_adapter_cxf_separate,Secure CXF Application on separate Jetty Engine>> as then you have more
|
||||
control over security for each application individually.
|
||||
|
||||
* You may need to have directory `WEB-INF` inside your project (even if your project is not web application) and create files `/WEB-INF/jetty-web.xml` and
|
||||
`/WEB-INF/keycloak.json` in similar way like it's in <<fake/../classic-war.adoc#_fuse_adapter_classic_war,Classic WAR application>>.
|
||||
Note you don't need `web.xml` as the security-constrains are declared in blueprint configuration file.
|
||||
|
||||
|
||||
* The `Import-Package` in `META-INF/MANIFEST.MF` needs to contain those imports:
|
||||
[source]
|
||||
----
|
||||
META-INF.cxf;version="[2.7,3.2)",
|
||||
META-INF.cxf.osgi;version="[2.7,3.2)";resolution:=optional,
|
||||
org.apache.cxf.transport.http;version="[2.7,3.2)",
|
||||
org.apache.cxf.*;version="[2.7,3.2)",
|
||||
com.fasterxml.jackson.jaxrs.json;version="[2.5,3)",
|
||||
org.eclipse.jetty.security;version="[8,10)",
|
||||
org.eclipse.jetty.util.security;version="[8,10)",
|
||||
org.keycloak.*;version="{{book.project.version}}",
|
||||
org.keycloak.adapters.jetty;version="{{book.project.version}}",
|
||||
*;resolution:=optional
|
||||
----
|
111
topics/oidc/java/fuse/cxf-separate.adoc
Normal file
111
topics/oidc/java/fuse/cxf-separate.adoc
Normal file
|
@ -0,0 +1,111 @@
|
|||
|
||||
[[_fuse_adapter_cxf_separate]]
|
||||
==== Secure Apache CXF Endpoint on separate Jetty
|
||||
|
||||
It's recommended to run your CXF endpoints secured by {{book.project.name}} on separate Jetty engine. This is the setup described in this section.
|
||||
|
||||
* You need to add `META-INF/spring/beans.xml` to your application and then declare `httpj:engine-factory` with Jetty SecurityHandler with
|
||||
injected `KeycloakJettyAuthenticator` inside. The configuration may look like this for CXF JAX-WS application:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<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="MIGfMA0..."/>
|
||||
<property name="bearerOnly" value="true"/>
|
||||
<property name="authServerUrl" value="http://localhost:8080/auth" />
|
||||
<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.ProductImpl"
|
||||
address="http://localhost:8282/ProductServiceCF" depends-on="kc-cxf-endpoint" />
|
||||
|
||||
</beans>
|
||||
----
|
||||
|
||||
* For the CXF JAX-RS application, the only difference might be in the configuration of the endpoint dependent on engine-factory:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<jaxrs:server serviceClass="org.keycloak.example.rs.CustomerService" address="http://localhost:8282/rest"
|
||||
depends-on="kc-cxf-endpoint">
|
||||
<jaxrs:providers>
|
||||
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
|
||||
</jaxrs:providers>
|
||||
</jaxrs:server>
|
||||
----
|
||||
|
||||
|
||||
* The `Import-Package` in `META-INF/MANIFEST.MF` needs to contain those imports:
|
||||
[source]
|
||||
----
|
||||
META-INF.cxf;version="[2.7,3.2)",
|
||||
META-INF.cxf.osgi;version="[2.7,3.2)";resolution:=optional,
|
||||
org.apache.cxf.bus;version="[2.7,3.2)",
|
||||
org.apache.cxf.bus.spring;version="[2.7,3.2)",
|
||||
org.apache.cxf.bus.resource;version="[2.7,3.2)",
|
||||
org.apache.cxf.transport.http;version="[2.7,3.2)",
|
||||
org.apache.cxf.*;version="[2.7,3.2)",
|
||||
org.springframework.beans.factory.config,
|
||||
org.eclipse.jetty.security;version="[8,10)",
|
||||
org.eclipse.jetty.util.security;version="[8,10)",
|
||||
org.keycloak.*;version="{{book.project.version}}"
|
||||
----
|
87
topics/oidc/java/fuse/fuse-admin.adoc
Normal file
87
topics/oidc/java/fuse/fuse-admin.adoc
Normal file
|
@ -0,0 +1,87 @@
|
|||
|
||||
[[_fuse_adapter_admin]]
|
||||
==== Secure Fuse Admin Services
|
||||
|
||||
===== SSH authentication to Fuse terminal
|
||||
|
||||
{{book.project.name}} mainly addresses usecases for authentication of web applications, however if your other web services and applications are protected
|
||||
with {{book.project.name}}, it may be good to protect non-web admin services like SSH with {{book.project.name}} credentials too. It's possible to do it
|
||||
by using JAAS login module, which allows to remotely connect to {{book.project.name}} and verify credentials based on
|
||||
<<fake/../../../oidc-generic.adoc#_resource_owner_password_credentials_flow,Resource Owner Password Credentials>> .
|
||||
|
||||
Example steps for enable SSH authentication:
|
||||
|
||||
* In {{book.project.name}} you need to create client (assume it's called `ssh-jmx-admin-client`), which will be used for SSH authentication.
|
||||
This client needs to have switch `Direct grant enabled` to true.
|
||||
|
||||
* You need to update/specify this property in file `$FUSE_HOME/etc/org.apache.karaf.shell.cfg`:
|
||||
|
||||
[source]
|
||||
----
|
||||
sshRealm=keycloak
|
||||
----
|
||||
|
||||
* Add file `$FUSE_HOME/etc/keycloak-direct-access.json` with the content similar to this (change based on your environment and {{book.project.name}} client settings):
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"realm": "demo",
|
||||
"resource": "ssh-jmx-admin-client",
|
||||
"realm-public-key": "MIGfMA...",
|
||||
"ssl-required" : "external",
|
||||
"auth-server-url" : "http://localhost:8080/auth",
|
||||
"credentials": {
|
||||
"secret": "password"
|
||||
}
|
||||
}
|
||||
----
|
||||
This file contains configuration of the client application, which is used by JAAS DirectAccessGrantsLoginModule from `keycloak` JAAS realm for SSH authentication.
|
||||
|
||||
* Start Fuse and install `keycloak` JAAS realm into Fuse. This could be done easily by installing `keycloak-jaas` feature, which has JAAS realm predefined
|
||||
(you are able to override it by using your own `keycloak` JAAS realm with higher ranking). Use those commands in Fuse terminal:
|
||||
|
||||
```
|
||||
features:addurl mvn:org.keycloak/keycloak-osgi-features/{{book.project.version}}/xml/features
|
||||
features:install keycloak-jaas
|
||||
```
|
||||
|
||||
* Now let's type this from your terminal to login via SSH as `admin` user:
|
||||
|
||||
```
|
||||
ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
|
||||
```
|
||||
|
||||
And login with password `password` . Note that your user needs to have realm role `admin` . The required roles are configured in `$FUSE_HOME/etc/org.apache.karaf.shell.cfg`
|
||||
|
||||
|
||||
===== JMX authentication
|
||||
|
||||
This may be needed in case if you really want to use jconsole or other external tool to perform remote connection to JMX through RMI. Otherwise it may
|
||||
be better to use just hawt.io/jolokia as jolokia agent is installed in hawt.io by default.
|
||||
|
||||
* In file `$FUSE_HOME/etc/org.apache.karaf.management.cfg` you can change this property:
|
||||
|
||||
[source]
|
||||
----
|
||||
jmxRealm=keycloak
|
||||
----
|
||||
|
||||
* You need `keycloak-jaas` feature and file `$FUSE_HOME/etc/keycloak-direct-access.json` as described in SSH section above.
|
||||
|
||||
* In jconsole you can fill URL like:
|
||||
|
||||
[source]
|
||||
----
|
||||
service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root
|
||||
----
|
||||
|
||||
and credentials: admin/password (based on the user with admin privileges according to your environment)
|
||||
|
||||
Note again that users without `admin` role are not able to login as they are not authorized. However users with access to Hawt.io admin console
|
||||
may be still able to access MBeans remotely via HTTP (Hawtio). So make sure to protect Hawt.io web console with same roles like JMX through RMI to
|
||||
really protect JMX mbeans.
|
||||
|
||||
|
||||
===== Secure Fuse admin console
|
||||
|
||||
Fuse admin console is Hawt.io. See http://hawt.io/configuration/index.html[Hawt.io documentation] for more info about how to secure it with {{book.project.name}}.
|
76
topics/oidc/java/fuse/servlet-whiteboard.adoc
Normal file
76
topics/oidc/java/fuse/servlet-whiteboard.adoc
Normal file
|
@ -0,0 +1,76 @@
|
|||
|
||||
[[_fuse_adapter_servlet_whiteboard]]
|
||||
==== Secure Servlet deployed as OSGI service
|
||||
|
||||
This is useful for the case, when you have sevlet class inside your OSGI bundle project, which is not deployed as classic WAR. Fuse uses
|
||||
https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+Whiteboard[Pax Web Whiteboard Extender] for deploy such servlet as web application.
|
||||
|
||||
The needed steps to secure your servlet with {{book.project.name}} are:
|
||||
|
||||
* Keycloak provides PaxWebIntegrationService, which allows to inject jetty-web.xml and configure security constraints for your application.
|
||||
You need to declare such service in `OSGI-INF/blueprint/blueprint.xml` inside your application. Note that your servlet needs to depend on it.
|
||||
The example configuration can look like this:
|
||||
[source,xml]
|
||||
----
|
||||
<?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>
|
||||
----
|
||||
|
||||
* You may need to have directory `WEB-INF` inside your project (even if your project is not web application) and create files `/WEB-INF/jetty-web.xml` and
|
||||
`/WEB-INF/keycloak.json` in similar way like it's in <<fake/../classic-war.adoc#_fuse_adapter_classic_war,Classic WAR application>>.
|
||||
Note you don't need `web.xml` as the security-constrains are declared in blueprint configuration file.
|
||||
|
||||
* The `Import-Package` in `META-INF/MANIFEST.MF` needs to contain at least those imports:
|
||||
[source]
|
||||
----
|
||||
org.keycloak.adapters.jetty;version="{{book.project.version}}",
|
||||
org.keycloak.adapters;version="{{book.project.version}}",
|
||||
org.keycloak.constants;version="{{book.project.version}}",
|
||||
org.keycloak.util;version="{{book.project.version}}",
|
||||
org.keycloak.*;version="{{book.project.version}}",
|
||||
*;resolution:=optional
|
||||
----
|
Loading…
Reference in a new issue