Merge pull request #6 from jenmalloy/securing-apps_fuse-edits

fixed RHSSO-638, 640, and 730-Fuse edits
This commit is contained in:
Jen Malloy 2017-02-26 20:46:31 -05:00 committed by GitHub
commit a1f58b5040
11 changed files with 192 additions and 228 deletions

View file

@ -1,13 +1,12 @@
[[_client_authentication_adapter]]
==== Client Authentication
When confidential OIDC client needs to send backchannel request (eg. exchange code for the token, or refresh token) it needs to authenticate
against {{book.project.name}} server. By default, there are 2 possibilities how to authenticate client:
When a confidential OIDC client needs to send a backchannel request (for example, to exchange code for the token, or to refresh the token) it needs to authenticate against the {{book.project.name}} server. By default, there are two ways to authenticate the client: client ID and client secret, or client authentication with signed JWT.
===== Client ID and Client Secret
This is traditional method described in OAuth2 specification. Client has a secret, which needs to be known to both adapter (application) and {{book.project.name}} server.
You can simply generate the secret for particular client in {{book.project.name}} admin console and then paste this secret in the `keycloak.json` file on the application's side:
This is the traditional method described in the OAuth2 specification. The client has a secret, which needs to be known to both the adapter (application) and the {{book.project.name}} server.
You can generate the secret for a particular client in the {{book.project.name}} administration console, and then paste this secret into the `keycloak.json` file on the application side:
[source]
@ -17,31 +16,25 @@ You can simply generate the secret for particular client in {{book.project.name}
}
----
===== Client authentication with signed JWT
===== Client Authentication with Signed JWT
This is based on the https://tools.ietf.org/html/rfc7523[RFC7523] specification. It works this way:
* Client must have the private key and certificate. In case of {{book.project.name}} this is available through the traditional `keystore` file, which is either available
on client application's classpath or somewhere on the filesystem.
* The client must have the private key and certificate. For {{book.project.name}} this is available through the traditional `keystore` file, which is either available on the client application's classpath or somewhere on the file system.
* Once the client application is started, it allows to download it's public key in https://self-issued.info/docs/draft-ietf-jose-json-web-key.html[JWKS] format on URL
like http://myhost.com/myapp/k_jwks assuming that http://myhost.com/myapp is the base URL of your client application. This URL can be used by the {{book.project.name}} (see below).
* Once the client application is started, it allows to download it's public key in https://self-issued.info/docs/draft-ietf-jose-json-web-key.html[JWKS] format using a URL such as \http://myhost.com/myapp/k_jwks, assuming that \http://myhost.com/myapp is the base URL of your client application. This URL can be used by {{book.project.name}} (see below).
* During authentication, client generates JWT token and signs it with his private key and sends it to the {{book.project.name}} in
the particular backchannel request (eg. code-to-token request) in the `client_assertion` parameter.
* During authentication, the client generates a JWT token and signs it with its private key and sends it to {{book.project.name}} in
the particular backchannel request (for example, code-to-token request) in the `client_assertion` parameter.
* {{book.project.name}} must have public key or certificate of the client, so that it can verify the signature on JWT. In {{book.project.name}} you either
need to configure client credentials for your client. First you need to choose `Signed JWT` as the method of authenticating your client in the tab `Credentials` in admin console.
Then you can choose either to:
** Configure the JWKS URL where {{book.project.name}} can download the client's public keys. This can be URL like http://myhost.com/myapp/k_jwks (see details above). This is flexible as
client can rotate it's keys anytime and {{book.project.name}} will then always download new keys when needed without need to change something in it's configuration. More acurately, {{book.project.name}}
will download new keys when it sees the token signed by unknown `kid` (Key ID).
** Upload the client's public key or certificate - either in PEM format, in JWK format or from keystore. With this option, public key is hardcoded and
needs to be changed anytime when client generates new keypair.
You can even generate your own keystore from {{book.project.name}} admin console if you don't have your own ready.
See {{book.project.doc_base_url}}{{book.project.doc_info_version_url}}{{book.adminguide.link}}[{{book.adminguide.name}}] for more details of setup in {{book.project.name}} admin console.
* {{book.project.name}} must have the public key or certificate of the client so that it can verify the signature on JWT. In {{book.project.name}} you need to configure client credentials for your client. First you need to choose `Signed JWT` as the method of authenticating your client in the tab `Credentials` in administration console.
Then you can choose to either:
** Configure the JWKS URL where {{book.project.name}} can download the client's public keys. This can be a URL such as \http://myhost.com/myapp/k_jwks (see details above). This option is the most flexible, since the client can rotate its keys anytime and {{book.project.name}} then always downloads new keys when needed without needing to change the configuration. More accurately, {{book.project.name}} downloads new keys when it sees the token signed by an unknown `kid` (Key ID).
** Upload the client's public key or certificate, either in PEM format, in JWK format, or from the keystore. With this option, the public key is hardcoded and must be changed when the client generates a new key pair.
You can even generate your own keystore from the {{book.project.name}} admininstration console if you don't have your own available.
For more details on how to set up the {{book.project.name}} administration console see {{book.project.doc_base_url}}{{book.project.doc_info_version_url}}{{book.adminguide.link}}[{{book.adminguide.name}}].
For setup on adapter's side you need to have something like this in your `keycloak.json` file:
For set up on the adapter side you need to have something like this in your `keycloak.json` file:
[source]
----
@ -57,18 +50,16 @@ For setup on adapter's side you need to have something like this in your `keyclo
}
----
With this configuration, the keystore file `keystore-client.jks` must be available on classpath in your WAR. If you don't use prefix `classpath:`
you can point to any file on the filesystem where client application is running.
With this configuration, the keystore file `keystore-client.jks` must be available on classpath in your WAR. If you do not use the prefix `classpath:`
you can point to any file on the file system where the client application is running.
{% if book.community %}
For inspiration, you can take a look at the examples distribution into the main demo example into the `product-portal` application.
===== Add your own client authentication method
This is possible. You will need to implement both client's side and server's side providers. See `Authentication SPI` section
in {{book.developerguide.link}}[{{book.developerguide.name}}] for more details.
===== Add Your Own Client Authentication Method
You can add your own client authentication method as well. You will need to implement both client-side and server-side providers. For more details see the `Authentication SPI` section in {{book.developerguide.link}}[{{book.developerguide.name}}].
{% endif %}

View file

@ -13,24 +13,22 @@ It leverages <<fake/../jetty9-adapter.adoc#_jetty9_adapter,Jetty 9 adapter>> as
under the covers and Jetty is used for running various kinds of web applications.
{% endif %}
WARNING: The only supported Fuse version is {{book.fuseVersion}}. If you use earlier versions of Fuse, it's possible that some functionalities won't work correctly.
Especially the http://hawt.io[Hawtio] integration won't work with earlier versions of Fuse.
WARNING: The only supported version of Fuse is {{book.fuseVersion}}. If you use earlier versions of Fuse, it is possible that some functions will not work correctly. In particular, the http://hawt.io[Hawtio] integration will not work with earlier versions of Fuse.
What is supported for Fuse is:
Security for the following items is supported for Fuse:
* 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.
* Security for SSH and JMX admin access.
* Security for http://hawt.io[Hawtio admin console]
* Classic WAR applications deployed on Fuse with https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+War[Pax Web War Extender]
* Servlets deployed on Fuse as OSGI services with https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+Whiteboard[Pax Web Whiteboard Extender]
* http://camel.apache.org/[Apache Camel] Jetty endpoints running with the http://camel.apache.org/jetty.html[Camel Jetty] component
* http://cxf.apache.org/[Apache CXF] endpoints running on their own separate http://cxf.apache.org/docs/jetty-configuration.html[Jetty engine]
* http://cxf.apache.org/[Apache CXF] endpoints running on the default engine provided by the CXF servlet
* SSH and JMX admin access
* http://hawt.io[Hawtio administration console]
===== How to secure your web applications inside Fuse
===== Securing Your Web Applications Inside Fuse
The first thing to do is usually installing of {{book.project.name}} Karaf feature. Then do the steps according to what type of application you want to secure.
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.
You must first install the {{book.project.name}} Karaf feature. Next you will need to perform the steps according to the type of application you want to secure.
All referenced web applications require injecting the {{book.project.name}} Jetty authenticator into the underlying Jetty server. The steps to achieve this depend on the application type. The details are described below.
{% 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

View file

@ -1,10 +1,10 @@
[[_fuse_adapter_camel]]
===== Apache Camel Application
===== Securing an 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:
You can secure your Apache camel endpoint using the http://camel.apache.org/jetty.html[camel-jetty] component by adding securityHandler with `KeycloakJettyAuthenticator` and the proper security constraints injected. You can add the `OSGI-INF/blueprint/blueprint.xml` file to your camel application with a similar configuration as below. The roles, security constraint mappings, and {{book.project.name}} adapter configuration might be slightly different depending on your environment and needs.
For example:
[source,xml]
----
@ -76,7 +76,7 @@ The roles, security constraint mappings and {{book.project.name}} adapter config
----
* The `Import-Package` in `META-INF/MANIFEST.MF` needs to contain those imports:
* The `Import-Package` in `META-INF/MANIFEST.MF` needs to contain these imports:
[source, subs="attributes"]
----
@ -95,13 +95,11 @@ org.osgi.service.event,
===== Camel RestDSL
Camel RestDSL is a Camel feature to define your REST endpoints in a fluent way.
But under the hood, the capability to provide all this magic, is still demanded to specific implementation classes and
you have to instruct them on how to integrate with {{book.project.name}}.
Camel RestDSL is a Camel feature to define your REST endpoints in a fluent way. But you still must use specific implementation classes and provide instructions on how to integrate with {{book.project.name}}.
The way to configure the integration mechanism depends on the Camel component that you configure your RestDSL defined routes to work with.
The way to configure the integration mechanism depends on the Camel component with which you configure your RestDSL-defined routes to work.
This is an example that show how to do it while using Jetty engine, with reference to some beans defined in the example above.
This is an example that shows how to do so while using the Jetty engine, with reference to some beans defined in the example above.
[source,xml]
----

View file

@ -1,12 +1,13 @@
[[_fuse_adapter_classic_war]]
===== Secure Classic WAR application
===== Securing a 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:
The needed steps to secure your WAR application are:
. Declare needed security constraints in the `/WEB-INF/web.xml` file. You also need to declare login-config and all the roles inside security-role.
+
For example:
+
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
@ -45,8 +46,10 @@ The example configuration can look like this:
</web-app>
----
* Add `jetty-web.xml` file with the authenticator to `/WEB-INF/jetty-web.xml` . Typically it will look like this:
. Add the `jetty-web.xml` file with the authenticator to the `/WEB-INF/jetty-web.xml` file.
+
For example:
+
[source,xml]
----
<?xml version="1.0"?>
@ -62,14 +65,13 @@ The example configuration can look like this:
</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. It is also possible to have this file available externally as described below.
* 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:
. Add the `/WEB-INF/keycloak.json` file to your {{book.project.name}} configuration. The format of this configuration file is described in the <<fake/../../java-adapter-config.adoc#_java_adapter_config,Java Adapters Config>> section. It is also possible to make this file available externally as described below.
. Ensure your WAR application imports `org.keycloak.adapters.jetty` and maybe some more packages in the `META-INF/MANIFEST.MF` file, under the `Import-Package` header. Using `maven-bundle-plugin` in your project properly generates OSGI headers in manifest.
Note that "*" resolution for the package does not import the `org.keycloak.adapters.jetty` package, since it is not used by the application or the Blueprint or Spring descriptor, but is rather used in the `jetty-web.xml` file.
+
The list of the packages to import might look like this:
+
[source, subs="attributes"]
----
org.keycloak.adapters.jetty;version="{{book.project.versionMvn}}",
@ -80,12 +82,11 @@ org.keycloak.*;version="{{book.project.versionMvn}}",
*;resolution:=optional
----
====== External adapter configuration
====== Configuring the External Adapter
This is for the case when you don't want adapter configuration file `keycloak.json` to be bundled inside your WAR application. Instead it will be available
externally and loaded based on naming conventions.
If you do not want the `keycloak.json` adapter configuration file to be bundled inside your WAR application, but instead available externally and loaded based on naming conventions, use this configuration method.
To enable the functionality you need to add this section to your `web.xml`:
To enable the functionality, add this section to your `web.xml` file:
[source,xml]
----
@ -95,8 +96,8 @@ To enable the functionality you need to add this section to your `web.xml`:
</context-param>
----
That component will use `keycloak.config` or `karaf.etc` java properties to look for a base folder to look for the configuration.
Inside one of those folders it will look for a file called `<your_web_context>-keycloak.json`.
That component uses `keycloak.config` or `karaf.etc` java properties to search for a base folder to locate the configuration.
Then inside one of those folders it searches for a file called `<your_web_context>-keycloak.json`.
So for example if your web application has context `my-portal`, then your adapter configuration will be loaded from the file `$FUSE_HOME/etc/my-portal-keycloak.json` .
So, for example, if your web application has context `my-portal`, then your adapter configuration is loaded from the `$FUSE_HOME/etc/my-portal-keycloak.json` file.

View file

@ -1,12 +1,11 @@
[[_fuse_adapter_cxf_builtin]]
===== Secure Apache CXF Endpoint on default Jetty Engine
===== Securing an Apache CXF Endpoint on the 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.
Some services automatically come with deployed servlets on startup. One such service is the CXF servlet running in the $$http://localhost:8181/cxf$$ context. Securing such endpoints can be complicated. One approach, which {{book.project.name}} is currently using,
is providing ServletReregistrationService, which undeploys a built-in servlet at startup, so you are able to redeploy it on a context secured by {{book.project.name}}.
The configuration file `OSGI-INF/blueprint/blueprint.xml` inside your application might resemble the one below. Note that it adds the JAX-RS `customerservice` endpoint, which is endpoint-specific to your application, but more importantly, secures the entire `/cxf` context.
[source,xml]
----
@ -72,17 +71,13 @@ which is endpoint specific to your application, but more importantly, it secures
</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.
As a result, all other CXF services running on the default CXF HTTP destination are also secured. Similarly, when the application is undeployed, the entire `/cxf` context becomes unsecured as well. For this reason, using your own Jetty engine for your applications as described in <<fake/../cxf-separate.adoc#_fuse_adapter_cxf_separate,Secure CXF Application on separate Jetty Engine>> then gives you more
control over security for each individual application.
* 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 `WEB-INF` directory might need to be inside your project (even if your project is not a web application). You also might need to edit the `/WEB-INF/jetty-web.xml` and `/WEB-INF/keycloak.json` files in a similar way as in <<fake/../classic-war.adoc#_fuse_adapter_classic_war,Classic WAR application>>.
Note that you do not need the `web.xml` file as the security constraints are declared in the blueprint configuration file.
* The `Import-Package` in `META-INF/MANIFEST.MF` needs to contain those imports:
* The `Import-Package` in `META-INF/MANIFEST.MF` must contain these imports:
[source, subs="attributes"]
----

View file

@ -1,12 +1,11 @@
[[_fuse_adapter_cxf_separate]]
===== Secure Apache CXF Endpoint on separate Jetty
===== Securing an Apache CXF Endpoint on a Separate Jetty Engine
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:
To run your CXF endpoints secured by {{book.project.name}} on separate Jetty engine, complete the following steps:
. Add `META-INF/spring/beans.xml` to your application and then declare `httpj:engine-factory` with Jetty SecurityHandler with injected `KeycloakJettyAuthenticator` inside. The configuration might resemble this one for a CXF JAX-WS application:
+
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
@ -79,9 +78,9 @@ injected `KeycloakJettyAuthenticator` inside. The configuration may look like th
</beans>
----
* For the CXF JAX-RS application, the only difference might be in the configuration of the endpoint dependent on engine-factory:
+
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"
@ -93,7 +92,7 @@ injected `KeycloakJettyAuthenticator` inside. The configuration may look like th
----
* The `Import-Package` in `META-INF/MANIFEST.MF` needs to contain those imports:
. The `Import-Package` in `META-INF/MANIFEST.MF` must contain those imports:
[source, subs="attributes"]
----

View file

@ -1,28 +1,27 @@
[[_fuse_adapter_admin]]
===== Secure Fuse Admin Services
===== Securing Fuse Administration Services
====== SSH authentication to Fuse terminal
====== Using 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
{{book.project.name}} mainly addresses use cases for authentication of web applications; however, if your other web services and applications are protected
with {{book.project.name}}, protecting non-web administration services such as SSH with {{book.project.name}} credentials is a best pracrice. You can do this using the JAAS login module, which allows remote connection to {{book.project.name}} and verifies credentials based on
<<fake/../../../oidc-generic.adoc#_resource_owner_password_credentials_flow,Resource Owner Password Credentials>>.
Example steps for enable SSH authentication:
To enable SSH authentication, complete the following steps:
* 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 Access Grants Enabled` to `On`.
* You need to update/specify this property in file `$FUSE_HOME/etc/org.apache.karaf.shell.cfg`:
. In {{book.project.name}} create a client (for example, `ssh-jmx-admin-client`), which will be used for SSH authentication.
This client needs to have `Direct Access Grants Enabled` selected to `On`.
. Update or specify this property in the `$FUSE_HOME/etc/org.apache.karaf.shell.cfg` file:
+
[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):
. Add the `$FUSE_HOME/etc/keycloak-direct-access.json` file with the content similar to the following (based on your environment and {{book.project.name}} client settings):
+
[source,json]
----
{
@ -35,52 +34,50 @@ sshRealm=keycloak
}
}
----
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. See JBoss Fuse documentation for more details). Use those commands in Fuse terminal:
This file specifies the client application configuration, which is used by JAAS DirectAccessGrantsLoginModule from the `keycloak` JAAS realm for SSH authentication.
. Start Fuse and install the `keycloak` JAAS realm into Fuse. The easiest way is to install the `keycloak-jaas` feature, which has the JAAS realm predefined; you can override it by using your own `keycloak` JAAS realm with higher ranking. For details see the JBoss Fuse documentation.
+
Use these commands in the Fuse terminal:
+
[source, subs="attributes"]
----
features:addurl mvn:org.keycloak/keycloak-osgi-features/{{book.project.versionMvn}}/xml/features
features:install keycloak-jaas
----
* Now let's type this from your terminal to login via SSH as `admin` user:
. Log in using SSH as `admin` user by typing the following in the terminal:
+
```
ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
```
And login with password `password`.
. Log in with password `password`.
NOTE: On some newer operating systems, you may also need to use this option of SSH command `-o HostKeyAlgorithms=+ssh-dss` because newer SSH clients
don't allow to use `ssh-dss` algorithm by default, but it's currently used by default in {{book.fuseVersion}} .
NOTE: On some later operating systems, you might also need to use this option of SSH command `-o HostKeyAlgorithms=+ssh-dss` because later SSH clients do not allow using the `ssh-dss` algorithm by default, but it is currently used by default in {{book.fuseVersion}}.
Note that the user needs to have realm role `admin` to perform all operations or another role to perform a subset of operations (for example, the viewer role to be able to only run read-only Karaf commands). The available roles are configured in `$FUSE_HOME/etc/org.apache.karaf.shell.cfg` or `$FUSE_HOME/etc/system.properties`.
Note that your user needs to have realm role `admin` if he wants to do everything or some other roles to be able to do just subset of operations
(eg. role `viewer` to be able to run just read-only Karaf commands) . The available roles are configured in `$FUSE_HOME/etc/org.apache.karaf.shell.cfg` or `$FUSE_HOME/etc/system.properties` .
====== Using JMX Authentication
JMX authentication might be necessary if you want to use jconsole or another external tool to remotely connect to JMX through RMI. Otherwise it might be better to use hawt.io/jolokia, since the jolokia agent is installed in hawt.io by default. For more details see <<fake/../hawtio.adoc#_hawtio,Hawtio Admin Console>>.
====== JMX authentication
To use JMX authentication, complete the following steps:
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. See <<fake/../hawtio.adoc#_hawtio,Hawtio Admin Console>> section for more details.
* In file `$FUSE_HOME/etc/org.apache.karaf.management.cfg` you can change this property:
. In the `$FUSE_HOME/etc/org.apache.karaf.management.cfg` file, 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.
. Install the `keycloak-jaas` feature and configure the `$FUSE_HOME/etc/keycloak-direct-access.json` file as described in SSH section above.
* In jconsole you can fill URL like:
. In jconsole you can use a URL such as:
[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)
and credentials: admin/password (based on the user with admin privileges according to your environment).

View file

@ -1,11 +1,11 @@
[[_hawtio]]
===== Secure Hawtio Admin Console
===== Securing the Hawtio Administration Console
The steps to secure Hawtio Admin Console with {{book.project.name}} are:
* Add these properties to the file `$FUSE_HOME/etc/system.properties` :
To secure the Hawtio Administration Console with {{book.project.name}}, complete the following steps:
. Add these properties to the `$FUSE_HOME/etc/system.properties` file:
+
[source]
----
hawtio.keycloakEnabled=true
@ -14,12 +14,10 @@ hawtio.keycloakClientConfig=${karaf.base}/etc/keycloak-hawtio-client.json
hawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal
----
* Create client in {{book.project.name}} admin console in your realm. Assuming you have {{book.project.name}} realm `demo` and you created client `hawtio-client`, which is marked
with `public` Access Type and has redirect URI pointing to Hawtio - http://localhost:8181/hawtio/* .
* Create file `keycloak-hawtio-client.json` in the directory `$FUSE_HOME/etc` and use the content like this (Change properties `realm`, `resource` and `auth-server-url` according to
your {{book.project.name}} environment. The property `resource` should point to the client created in previous step. This file is used by the client (Hawtio Javascript application) side.
. Create a client in the {{book.project.name}} administration console in your realm. Assumptions are that you have a {{book.project.name}} realm `demo` and you created a client `hawtio-client`, which is marked with `public` Access Type and has a redirect URI pointing to Hawtio: \http://localhost:8181/hawtio/*.
. Create the `keycloak-hawtio-client.json` file in the `$FUSE_HOME/etc` directory using the similar content as below. Change properties `realm`, `resource` and `auth-server-url` according to your {{book.project.name}} environment. The property `resource` must point to the client created in the previous step. This file is used by the client (Hawtio Javascript application) side.
+
[source,json]
----
{
@ -31,10 +29,8 @@ your {{book.project.name}} environment. The property `resource` should point to
}
----
* Create file `keycloak-hawtio.json` in the directory `$FUSE_HOME/etc` and use the content like this (Change properties `realm` and `auth-server-url` according to
your {{book.project.name}} environment. This file is used by the adapters on server (JAAS Login module) side.
. Create the `keycloak-hawtio.json` file in the `$FUSE_HOME/etc` dicrectory using similar content as below. Change the `realm` and `auth-server-url` properties according to your {{book.project.name}} environment. This file is used by the adapters on the server (JAAS Login module) side.
+
[source,json]
----
{
@ -48,34 +44,32 @@ your {{book.project.name}} environment. This file is used by the adapters on ser
}
----
* Start {{book.fuseVersion}} and install feature `keycloak` if you didn't already. The commands in Karaf terminal are like:
. Start {{book.fuseVersion}} and install the keycloak feature if you have not already. The commands in Karaf terminal are similar to this example:
+
[source, subs="attributes"]
----
features:addurl mvn:org.keycloak/keycloak-osgi-features/{{book.project.versionMvn}}/xml/features
features:install keycloak
----
* Go to http://localhost:8181/hawtio and login as some user from your {{book.project.name}} realm. See file `$FUSE_HOME/etc/system.properties` and property `hawtio.roles` .
Just those with some of the role are able to successfully authenticate to Hawtio and do something here.
. Go to http://localhost:8181/hawtio and log in as a user from your {{book.project.name}} realm.
+
Note that the user needs to have the proper realm role to successfully authenticate to Hawtio. The available roles are configured in the `$FUSE_HOME/etc/system.properties` file in `hawtio.roles`.
====== Securing Hawtio on EAP
====== Secure Hawtio on EAP
To run Hawtio on the Wildfly 10 server, complete the following steps:
This subsection contains needed steps for the case, when you want to run Hawtio on the Wildfly 10 server.
. Set up {{book.project.name}} as in the Securing the Hawtio Administration Console section above. The following assumptions apply: you have a {{book.project.name}} realm `demo` and client `hawtio-client`, and your {{book.project.name}} is running on `localhost:8080` while the Wildfly server with deployed Hawtio will be running on `localhost:8181`.
* Setup {{book.project.name}} similarly like mentioned above in the section for securing Hawtion on JBoss Fuse. So assuming you have {{book.project.name}} realm `demo`
and client `hawtio-client`. Assumption is that your {{book.project.name}} is running on `localhost:8080` when the Wildfly with deployed hawtio will be running on `localhost:8181`.
. Copy the `hawtio.war` archive to the `$WILDFLY_HOME/standalone/configuration` directory. For more details about deploying Hawtio see the Fuse Hawtio documentation.
* Copy `hawtio.war` to the `$WILDFLY_HOME/standalone/configuration` directory. See Hawtio/Fuse documentation for more details about the Hawtio deployment.
. Copy the `keycloak-hawtio.json` and `keycloak-hawtio-client.json` files with the above content to the `$WILDFLY_HOME/standalone/configuration` directory.
* Copy files `keycloak-hawtio.json` and `keycloak-hawtio-client.json` with the above content to the `$WILDFLY_HOME/standalone/configuration` directory.
* Install {{book.project.name}} adapter subsystem to your Wildfly as described in the <<fake/../../jboss-adapter.adoc#_jboss_adapter,JBoss adapter documentation>>
* In `$WILDFLY_HOME/standalone/configuration/standalone.xml` configure system properties like this:
. Install the {{book.project.name}} adapter subsystem to your Wildfly server as described in the <<fake/../../jboss-adapter.adoc#_jboss_adapter,JBoss adapter documentation>>
. In the `$WILDFLY_HOME/standalone/configuration/standalone.xml` file configure the system properties as in this example:
+
[source,xml]
----
<extensions>
@ -93,8 +87,8 @@ and client `hawtio-client`. Assumption is that your {{book.project.name}} is run
</system-properties>
----
Also add hawtio realm to this file to the `security-domains` section:
. Add the Hawtio realm to the same file in the `security-domains` section:
+
[source,xml]
----
<security-domain name="hawtio" cache-type="default">
@ -106,9 +100,9 @@ Also add hawtio realm to this file to the `security-domains` section:
</security-domain>
----
Finally add the `secure-deployment` section `hawtio` to the adapter subsystem. It should ensure that Hawtio WAR is able to find the JAAS login module classes.
. Add the `secure-deployment` section `hawtio` to the adapter subsystem. This ensures that the Hawtio WAR is able to find the JAAS login module classes.
+
[source,xml]
----
<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
@ -116,14 +110,13 @@ Finally add the `secure-deployment` section `hawtio` to the adapter subsystem. I
</subsystem>
----
* Restart Wildfly server with Hawtio
. Restart the Wildfly server with Hawtio:
+
[source,xml]
----
cd $WILDFLY_HOME/bin
./standalone.sh -Djboss.socket.binding.port-offset=101
----
* Access Hawtio on http://localhost:8181/hawtio . It will be secured by the {{book.project.name}} .
. Access Hawtio at http://localhost:8181/hawtio. It is secured by {{book.project.name}}.

View file

@ -1,35 +1,34 @@
[[_fuse_install_feature]]
===== Install Feature
===== Installing the Keycloak Feature
First thing to be done is to install the feature `keycloak` into the JBoss Fuse environment. This will install the Fuse adapter
together with all needed 3rd party dependencies. There are 2 possibilities to install it.
You must first install the `keycloak` feature in the JBoss Fuse environment. The keycloak feature includes the Fuse adapter and all third-party dependencies. You can install it either from the Maven repository or from an archive.
====== Installing from the Maven Repository
====== Install from Maven Repository
You need to be online and have access to the maven repository.
As a prequisite, you need to be online and have access to the Maven repository.
{% if book.community %}
For community it's sufficient to be online as all the artifacts and 3rd party dependencies should be available in maven central repository.
For community it's sufficient to be online as all the artifacts and 3rd party dependencies should be available in the maven central repository.
{% endif %}
{% if book.product %}
For {{book.project.name}} you first need to configure proper maven repository, so you can install the artifacts. You can find on
https://access.redhat.com/maven-repository[Maven Repository] page what's the proper maven repository containing the bits.
For {{book.project.name}} you first need to configure a proper Maven repository, so you can install the artifacts. For more information see the
https://access.redhat.com/maven-repository[Maven Repository] page.
Assuming it's https://maven.repository.redhat.com/ga/ you will need to add this to the file `$FUSE_HOME/etc/org.ops4j.pax.url.mvn.cfg`
and add the repository to the list of supported repositories. For example it may look like this:
Assuming the Maven repository is https://maven.repository.redhat.com/ga/, add the following to the `$FUSE_HOME/etc/org.ops4j.pax.url.mvn.cfg` file and add the repository to the list of supported repositories. For example:
[source]
----
org.ops4j.pax.url.mvn.repositories= \
org.ops4j.pax.url.mvn.repositories= \
https://maven.repository.redhat.com/ga@id=redhat.product.repo
http://repo1.maven.org/maven2@id=maven.central.repo, \
...
----
{% endif %}
You need to start {{book.fuseVersion}} and then in the Karaf terminal you type this:
To install the keycloak feature using the maven repository complete the following steps:
. Start {{book.fuseVersion}}; then in the Karaf terminal type:
[source,subs="attributes"]
----
@ -37,43 +36,45 @@ features:addurl mvn:org.keycloak/keycloak-osgi-features/{{book.project.versionMv
features:install keycloak
----
Then you may need to install Jetty 9 feature:
. You might also need to install the Jetty 9 feature:
[source]
----
features:install keycloak-jetty9-adapter
----
NOTE: If you are on JBoss Fuse 6.2 or older, you should use `keycloak-jetty8-adapter` . However it's highly recommended to
rather upgrade to {{book.fuseVersion}} instead.
NOTE: If you are using JBoss Fuse 6.2 or later, you should use `keycloak-jetty8-adapter`. However, upgrading {{book.fuseVersion}} instead.
Then you can check that requested features were installed:
. Ensure that the features were installed:
[source]
----
features:list | grep keycloak
----
====== Install from ZIP bundle
====== Installing from the ZIP bundle
This is useful if you are offline and/or don't want to use maven for download jar files and other artifacts. Once you download ZIP bundle of {{book.project.name}} Fuse adapter,
you will need to unzip it into the root directory of JBoss Fuse. This should install the dependencies under the `system` directory. Use this for {{book.fuseVersion}} :
This is useful if you are offline or do not want to use Maven to obtain the JAR files and other artifacts.
To install the Fuse adapter from the ZIP archive, complete the following steps:
. Download the {{book.project.name}} Fuse adapter ZIP archive.
. Unzip it into the root directory of JBoss Fuse. The dependencies are then installed under the `system` directory. You can overwrite all existing jar files.
+
Use this for {{book.fuseVersion}}:
+
[source,subs="attributes"]
----
cd /path-to-fuse/jboss-fuse-6.3.0.redhat-198
unzip -q /path-to-adapter-zip/keycloak-fuse-adapter-dist-{{book.project.versionMvn}}.zip
----
Feel free to overwrite all already existing jars. Once you unzip archive, you can start the Fuse and again run commands in fuse/karaf terminal
. Start Fuse and run these commands in the fuse/karaf terminal:
+
[source,subs="attributes"]
----
features:addurl mvn:org.keycloak/keycloak-osgi-features/{{book.project.versionMvn}}/xml/features
features:install keycloak
----
And also install the corresponding Jetty adapter. The difference from the previous part is, that nothing will be downloaded from maven repository as the artifacts were
available directly in JBoss Fuse `system` directory.
. Install the corresponding Jetty adapter. Since the artifacts are available directly in the JBoss Fuse `system` directory, you do not need to use the Maven repository.

View file

@ -1,16 +1,14 @@
[[_fuse_adapter_servlet_whiteboard]]
===== Secure Servlet deployed as OSGI service
===== Securing a Servlet Deployed as an 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.
You can use this method if you have a servlet class inside your OSGI bundled project that is not deployed as a classic WAR application. Fuse uses https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+Whiteboard[Pax Web Whiteboard Extender] to deploy such servlets as web applications.
The needed steps to secure your servlet with {{book.project.name}} are:
* {{book.project.name}} 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:
To secure your servlet with {{book.project.name}}, complete the following steps:
. {{book.project.name}} provides PaxWebIntegrationService, which allows injecting jetty-web.xml and configuring security constraints for your application. You need to declare such services in the `OSGI-INF/blueprint/blueprint.xml` file inside your application. Note that your servlet needs to depend on it.
An example configuration:
+
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
@ -61,12 +59,11 @@ The needed steps to secure your servlet with {{book.project.name}} are:
</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:
* You might need to have the `WEB-INF` directory inside your project (even if your project is not a web application) and create the `/WEB-INF/jetty-web.xml` and `/WEB-INF/keycloak.json` files as in the <<fake/../classic-war.adoc#_fuse_adapter_classic_war,Classic WAR application>> section.
Note you don't need the `web.xml` file as the security-constraints are declared in the blueprint configuration file.
. The `Import-Package` in `META-INF/MANIFEST.MF` must contain at least these imports:
+
[source, subs="attributes"]
----
org.keycloak.adapters.jetty;version="{{book.project.versionMvn}}",

View file

@ -1,81 +1,75 @@
=== Other OpenID Connect libraries
=== Other OpenID Connect Libraries
{{book.project.name}} can be secured by supplied adapters that usually are easier to use and provide better integration with {{book.project.name}}. However,
if there is no adapter available for your programming language, framework or platform you may opt to use a generic OpenID Connect Resource Provider (RP) library
instead. This chapter describes details specific to {{book.project.name}} and doesn't go into low-level details of the protocols. For more details refer to the
http://openid.net/connect/[OpenID Connect specifications] and https://tools.ietf.org/html/rfc6749[OAuth2 specification].
{{book.project.name}} can be secured by supplied adapters that are usually easier to use and provide better integration with {{book.project.name}}. However, if an adapter is not available for your programming language, framework, or platform you might opt to use a generic OpenID Connect Resource Provider (RP) library instead. This chapter describes details specific to {{book.project.name}} and does not contain specific protocol details. For more information see the http://openid.net/connect/[OpenID Connect specifications] and https://tools.ietf.org/html/rfc6749[OAuth2 specification].
==== Endpoints
The most important endpoint to know is the `well-known` configuration endpoint. It lists endpoints and other configuration options relevant to the OpenID
Connect implementation in {{book.project.name}}. The endpoint is:
The most important endpoint to understand is the `well-known` configuration endpoint. It lists endpoints and other configuration options relevant to the OpenID Connect implementation in {{book.project.name}}. The endpoint is:
....
/realms/{realm-name}/.well-known/openid-configuration
....
To get the full URL add the base URL for {{book.project.name}} and replace `{realm-name}` with the name of your realm. For example:
To obtain the full URL, add the base URL for {{book.project.name}} and replace `{realm-name}` with the name of your realm. For example:
$$http://localhost:8080/auth/realms/master/.well-known/openid-configuration$$
Some RP libraries will retrieve all required endpoints from this endpoint, but for others you may need to list the endpoints individually.
Some RP libraries retrieve all required endpoints from this endpoint, but for others you might need to list the endpoints individually.
===== Authorization Endpoint
....
/realms/{realm-name}/protocol/openid-connect/auth
....
Performs authentication of the end-user. This is done by redirecting user agent to this endpoint.
The authorization endpoint performs authentication of the end-user. This is done by redirecting the user agent to this endpoint.
For more details see http://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint[Authorization Endpoint] section in OpenID Connect specification.
For more details see the http://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint[Authorization Endpoint] section in the OpenID Connect specification.
===== Token Endpoint
....
/realms/{realm-name}/protocol/openid-connect/token
....
Used to obtain tokens. Tokens can either be obtained by exchanging an authorization code or by supplying credentials directly depending on what flow is used.
The token endpoint is used to obtain tokens. Tokens can either be obtained by exchanging an authorization code or by supplying credentials directly depending on what flow is used.
The token endpoint is also used to obtain new access tokens when they expire.
For more details see http://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint[Token Endpoint] section in OpenID Connect specification.
For more details see the http://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint[Token Endpoint] section in the OpenID Connect specification.
===== Userinfo Endpoint
....
/realms/{realm-name}/protocol/openid-connect/userinfo
....
Returns standard claims about the authenticated user. Protected by a bearer token.
The userinfo endpoint returns standard claims about the authenticated user, and is protected by a bearer token.
For more details see http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[Userinfo Endpoint] section in OpenID Connect specification.
For more details see the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[Userinfo Endpoint] section in the OpenID Connect specification.
===== Logout Endpoint
....
/realms/{realm-name}/protocol/openid-connect/logout
....
Logs out the authenticated user.
The logout endpoint logs out the authenticated user.
User agent can be redirected to the endpoint in which case the active user session will be logged out. Afterwards the user agent is redirected back to the application.
The user agent can be redirected to the endpoint, in which case the active user session is logged out. Afterward the user agent is redirected back to the application.
The endpoint can also be invoked directly by the application. To invoke this endpoint directly the refresh token needs to be included as well as credentials
required to authenticate the client.
The endpoint can also be invoked directly by the application. To invoke this endpoint directly the refresh token needs to be included as well as the credentials required to authenticate the client.
===== Certificate Endpoint
....
/realms/{realm-name}/protocol/openid-connect/certs
....
Public key used by realm encoded as a JSON Web Key (JWK). This key can be used to verify tokens issued by {{book.project.name}} without making invocations to
the server.
The certificate endpoint is the public key or keys used by the realm, encoded as a JSON Web Key (JWK). This key or keys can be used to verify tokens issued by {{book.project.name}} without making invocations to the server. Although multiple keys can be listed, only one key is used for verification.
For more details see https://tools.ietf.org/html/rfc7517[JSON Web Key specification].
For more details see the https://tools.ietf.org/html/rfc7517[JSON Web Key specification].
===== Introspection Endpoint
....
/realms/{realm-name}/protocol/openid-connect/token/introspect
....
Used to retrieve the active state of a token. Protected by a bearer token and can only be invoked by confidential clients.
The introspection endpoint is used to retrieve the active state of a token. It is protected by a bearer token and can only be invoked by confidential clients.
For more details see https://tools.ietf.org/html/rfc7662[OAuth 2.0 Token Introspection specification].
@ -84,9 +78,9 @@ For more details see https://tools.ietf.org/html/rfc7662[OAuth 2.0 Token Introsp
/realms/{realm-name}/clients-registrations/openid-connect
....
Used to dynamically register clients.
The dynamic client registration endpoint is used to dynamically register clients.
For more details see <<fake/../../client-registration.adoc#_client_registration,Client Registration chapter>> and the
For more details see the <<fake/../../client-registration.adoc#_client_registration,Client Registration chapter>> and the
https://openid.net/specs/openid-connect-registration-1_0.html[OpenID Connect Dynamic Client Registration specification].