2016-02-03 10:20:22 +00:00
|
|
|
<!--
|
|
|
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
|
|
~ and other contributors as indicated by the @author tags.
|
|
|
|
~
|
|
|
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
~ you may not use this file except in compliance with the License.
|
|
|
|
~ You may obtain a copy of the License at
|
|
|
|
~
|
|
|
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
~
|
|
|
|
~ Unless required by applicable law or agreed to in writing, software
|
|
|
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
~ See the License for the specific language governing permissions and
|
|
|
|
~ limitations under the License.
|
|
|
|
-->
|
|
|
|
|
2015-10-06 19:56:44 +00:00
|
|
|
<chapter id="jboss-adapter">
|
|
|
|
<title>JBoss/Wildfly Adapter</title>
|
|
|
|
<para>
|
|
|
|
To be able to secure WAR apps deployed on JBoss EAP 6.x or Wildfly, you must install and
|
|
|
|
configure the Keycloak SAML Adapter Subsystem. You then provide a keycloak
|
2015-11-09 14:12:01 +00:00
|
|
|
config, <literal>/WEB-INF/keycloak-saml.xml</literal> file in your WAR and change the auth-method to KEYCLOAK-SAML within web.xml.
|
2015-10-06 19:56:44 +00:00
|
|
|
Both methods are described in this section.
|
|
|
|
</para>
|
|
|
|
<section id="jboss-adapter-installation">
|
|
|
|
<title>Adapter Installation</title>
|
|
|
|
<para>
|
|
|
|
SAML Adapters are no longer included with the appliance or war distribution.Each adapter is a separate download on
|
|
|
|
the Keycloak download site. They are also available as a maven artifact.
|
|
|
|
</para>
|
|
|
|
<para>
|
2015-11-09 14:12:01 +00:00
|
|
|
Install on Wildfly 9 or 10:
|
2015-10-06 19:56:44 +00:00
|
|
|
<programlisting>
|
|
|
|
$ cd $WILDFLY_HOME
|
2015-11-09 14:12:01 +00:00
|
|
|
$ unzip keycloak-saml-wildfly-adapter-dist.zip
|
2015-10-06 19:56:44 +00:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Install on JBoss EAP 6.x:
|
|
|
|
<programlisting>
|
|
|
|
$ cd $JBOSS_HOME
|
|
|
|
$ unzip keycloak-saml-eap6-adapter-dist.zip
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
This zip file creates new JBoss Modules specific to the Wildfly Keycloak SAML Adapter within your Wildfly distro.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
After adding the Keycloak modules, you must then enable the Keycloak SAML Subsystem within your app server's server configuration:
|
|
|
|
<literal>domain.xml</literal> or <literal>standalone.xml</literal>.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
There is a CLI script that will help you modify your server configuration. Start the server and run the script
|
|
|
|
from the server's bin directory:
|
|
|
|
<programlisting>
|
|
|
|
$ cd $JBOSS_HOME/bin
|
2015-11-30 11:53:29 +00:00
|
|
|
$ jboss-cli.sh -c --file=adapter-install-saml.cli
|
2015-10-06 19:56:44 +00:00
|
|
|
</programlisting>
|
|
|
|
The script will add the extension, subsystem, and optional security-domain as described below.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
<server xmlns="urn:jboss:domain:1.4">
|
|
|
|
|
|
|
|
<extensions>
|
|
|
|
<extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
|
|
|
|
...
|
|
|
|
</extensions>
|
|
|
|
|
|
|
|
<profile>
|
2015-11-09 14:12:01 +00:00
|
|
|
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"/>
|
2015-10-06 19:56:44 +00:00
|
|
|
...
|
|
|
|
</profile>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The keycloak security domain should be used with EJBs and other components when you need the security context created
|
|
|
|
in the secured web tier to be propagated to the EJBs (other EE component) you are invoking. Otherwise
|
|
|
|
this configuration is optional.
|
|
|
|
</para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
<server xmlns="urn:jboss:domain:1.4">
|
|
|
|
<subsystem xmlns="urn:jboss:domain:security:1.2">
|
|
|
|
<security-domains>
|
|
|
|
...
|
|
|
|
<security-domain name="keycloak">
|
|
|
|
<authentication>
|
|
|
|
<login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule"
|
|
|
|
flag="required"/>
|
|
|
|
</authentication>
|
|
|
|
</security-domain>
|
|
|
|
</security-domains>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
<para>
|
|
|
|
For example, if you have a JAX-RS service that is an EJB within your WEB-INF/classes directory, you'll want
|
|
|
|
to annotate it with the @SecurityDomain annotation as follows:
|
|
|
|
</para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
import org.jboss.ejb3.annotation.SecurityDomain;
|
|
|
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
|
|
|
|
|
|
|
import javax.annotation.security.RolesAllowed;
|
|
|
|
import javax.ejb.EJB;
|
|
|
|
import javax.ejb.Stateless;
|
|
|
|
import javax.ws.rs.GET;
|
|
|
|
import javax.ws.rs.Path;
|
|
|
|
import javax.ws.rs.Produces;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
@Path("customers")
|
|
|
|
@Stateless
|
|
|
|
@SecurityDomain("keycloak")
|
|
|
|
public class CustomerService {
|
|
|
|
|
|
|
|
@EJB
|
|
|
|
CustomerDB db;
|
|
|
|
|
|
|
|
@GET
|
|
|
|
@Produces("application/json")
|
|
|
|
@NoCache
|
|
|
|
@RolesAllowed("db_user")
|
|
|
|
public List<String> getCustomers() {
|
|
|
|
return db.getCustomers();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
<para>
|
|
|
|
We hope to improve our integration in the future so that you don't have to specify the @SecurityDomain
|
|
|
|
annotation when you want to propagate a keycloak security context to the EJB tier.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
<section>
|
|
|
|
<title>Required Per WAR Configuration</title>
|
|
|
|
<para>
|
|
|
|
This section describes how to secure a WAR directly by adding config and editing files within your WAR package.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The first thing you must do is create
|
|
|
|
a <literal>keycloak-saml.xml</literal> adapter config file within the <literal>WEB-INF</literal> directory
|
|
|
|
of your WAR. The format of this config file is describe in the <link linkend='adapter-config'>general adapter configuration</link>
|
|
|
|
section.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Next you must set the <literal>auth-method</literal> to <literal>KEYCLOAK-SAML</literal> in <literal>web.xml</literal>. You also
|
|
|
|
have to use standard servlet security to specify role-base constraints on your URLs. Here's an example
|
|
|
|
pulled from one of the examples that comes distributed with Keycloak.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<programlisting>
|
|
|
|
<![CDATA[
|
|
|
|
<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>
|
|
|
|
|
|
|
|
<security-constraint>
|
|
|
|
<web-resource-collection>
|
|
|
|
<web-resource-name>Admins</web-resource-name>
|
|
|
|
<url-pattern>/admin/*</url-pattern>
|
|
|
|
</web-resource-collection>
|
|
|
|
<auth-constraint>
|
|
|
|
<role-name>admin</role-name>
|
|
|
|
</auth-constraint>
|
|
|
|
<user-data-constraint>
|
|
|
|
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
|
|
|
</user-data-constraint>
|
|
|
|
</security-constraint>
|
|
|
|
<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>
|
|
|
|
<user-data-constraint>
|
|
|
|
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
|
|
|
</user-data-constraint>
|
|
|
|
</security-constraint>
|
|
|
|
|
|
|
|
<login-config>
|
|
|
|
<auth-method>KEYCLOAK-SAML</auth-method>
|
|
|
|
<realm-name>this is ignored currently</realm-name>
|
|
|
|
</login-config>
|
|
|
|
|
|
|
|
<security-role>
|
|
|
|
<role-name>admin</role-name>
|
|
|
|
</security-role>
|
|
|
|
<security-role>
|
|
|
|
<role-name>user</role-name>
|
|
|
|
</security-role>
|
|
|
|
</web-app>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
</section>
|
2015-11-09 14:12:01 +00:00
|
|
|
<section>
|
|
|
|
<title>Securing WARs via Keycloak SAML Subsystem</title>
|
|
|
|
<para>
|
|
|
|
You do not have to crack open a WAR to secure it with Keycloak. Alternatively, you can externally secure
|
|
|
|
it via the Keycloak SAML Adapter Subsystem. While you don't have to specify KEYCLOAK-SAML as an <literal>auth-method</literal>,
|
|
|
|
you still have to define the <literal>security-constraints</literal> in <literal>web.xml</literal>. You do
|
|
|
|
not, however, have to create a <literal>WEB-INF/keycloak-saml.xml</literal> file. This metadata is instead defined
|
|
|
|
within XML in your server's <literal>domain.xml</literal> or <literal>standalone.xml</literal> subsystem
|
|
|
|
configuration section.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
<extensions>
|
|
|
|
<extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
|
|
|
|
</extensions>
|
|
|
|
|
|
|
|
<profile>
|
|
|
|
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
|
|
|
|
<secure-deployment name="WAR MODULE NAME.war">
|
|
|
|
<SP entityID="APPLICATION URL">
|
|
|
|
...
|
|
|
|
</SP>
|
|
|
|
</secure-deployment>
|
|
|
|
</subsystem>
|
|
|
|
</profile>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The <literal>secure-deployment</literal> <literal>name</literal> attribute identifies the WAR you want
|
|
|
|
to secure. Its value is the <literal>module-name</literal> defined in <literal>web.xml</literal> with
|
|
|
|
<literal>.war</literal> appended. The rest of the configuration uses the same XML syntax as
|
|
|
|
<literal>keycloak-saml.xml</literal> configuration defined in <link linkend='adapter-config'>general adapter configuration</link>.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
An example configuration:
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
|
|
|
|
<secure-deployment name="saml-post-encryption.war">
|
|
|
|
<SP entityID="http://localhost:8080/sales-post-enc/"
|
|
|
|
sslPolicy="EXTERNAL"
|
|
|
|
nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
|
|
|
|
logoutPage="/logout.jsp"
|
|
|
|
forceAuthentication="false">
|
|
|
|
<Keys>
|
|
|
|
<Key signing="true" encryption="true">
|
|
|
|
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
|
|
|
|
<PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/>
|
|
|
|
<Certificate alias="http://localhost:8080/sales-post-enc/"/>
|
|
|
|
</KeyStore>
|
|
|
|
</Key>
|
|
|
|
</Keys>
|
|
|
|
<PrincipalNameMapping policy="FROM_NAME_ID"/>
|
|
|
|
<RoleIdentifiers>
|
|
|
|
<Attribute name="Role"/>
|
|
|
|
</RoleIdentifiers>
|
|
|
|
<IDP entityID="idp">
|
|
|
|
<SingleSignOnService signRequest="true"
|
|
|
|
validateResponseSignature="true"
|
|
|
|
requestBinding="POST"
|
|
|
|
bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
|
|
|
|
|
|
|
|
<SingleLogoutService
|
|
|
|
validateRequestSignature="true"
|
|
|
|
validateResponseSignature="true"
|
|
|
|
signRequest="true"
|
|
|
|
signResponse="true"
|
|
|
|
requestBinding="POST"
|
|
|
|
responseBinding="POST"
|
|
|
|
postBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"
|
|
|
|
redirectBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
|
|
|
|
<Keys>
|
|
|
|
<Key signing="true" >
|
|
|
|
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
|
|
|
|
<Certificate alias="saml-demo"/>
|
|
|
|
</KeyStore>
|
|
|
|
</Key>
|
|
|
|
</Keys>
|
|
|
|
</IDP>
|
|
|
|
</SP>
|
|
|
|
</secure-deployment>
|
|
|
|
</subsystem>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
</section>
|
2015-10-06 19:56:44 +00:00
|
|
|
</chapter>
|