This commit is contained in:
Bill Burke 2014-01-12 20:57:31 -05:00
parent ddbb63f3d1
commit 8b66234ab9
8 changed files with 1177 additions and 0 deletions

119
docbook/pom.xml Executable file
View file

@ -0,0 +1,119 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-reference-guide-${translation}</artifactId>
<version>1.0-alpha-1-SNAPSHOT</version>
<packaging>jdocbook</packaging>
<name>Keycloak Reference Guide (${translation})</name>
<description/>
<repositories>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
<!--
<repository>
<id>repo1.maven.org</id>
<url>http://repo1.maven.org/maven2</url>
</repository> -->
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</pluginRepository>
<!--
<pluginRepository>
<id>maven2-repository.dev.java.net</id>
<url>http://download.java.net/maven/2</url>
</pluginRepository>
<pluginRepository>
<id>plugin repo1.maven.org</id>
<url>http://repo1.maven.org/maven2</url>
</pluginRepository>
-->
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-jdocbook-plugin</artifactId>
<version>2.3.8</version>
<extensions>true</extensions>
<dependencies>
<dependency>
<groupId>org.jboss.pressgang</groupId>
<artifactId>pressgang-xslt-ns</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.jboss.pressgang</groupId>
<artifactId>pressgang-jdocbook-style</artifactId>
<type>jdocbook-style</type>
<version>2.0.2</version>
</dependency>
</dependencies>
<configuration>
<sourceDocumentName>master.xml</sourceDocumentName>
<masterTranslation>en-US</masterTranslation>
<sourceDirectory>reference/en</sourceDirectory>
<imageResource>
<directory>reference/en</directory>
<includes>
<include>images/*</include>
</includes>
</imageResource>
<formats>
<format>
<formatName>html_single</formatName>
<stylesheetResource>classpath:/xslt/org/jboss/xhtml-single.xsl</stylesheetResource>
<finalName>index.html</finalName>
<!-- <profilingTypeName>two_pass</profilingTypeName> -->
</format>
<format>
<formatName>html</formatName>
<stylesheetResource>classpath:/xslt/org/jboss/xhtml.xsl</stylesheetResource>
<finalName>index.html</finalName>
<!-- <profilingTypeName>two_pass</profilingTypeName> -->
</format>
<format>
<formatName>pdf</formatName>
<stylesheetResource>classpath:/xslt/org/jboss/pdf.xsl</stylesheetResource>
<finalName>${project.artifactId}.pdf</finalName>
</format>
<!--<format>-->
<!--<formatName>eclipse</formatName>-->
<!--<stylesheetResource>classpath:/xslt/org/jboss/eclipse.xsl</stylesheetResource>-->
<!--<finalName>${project.artifactId}.html</finalName>-->
<!--</format>-->
</formats>
<injections>
<injection>
<name>project.version</name>
<value>${project.version}</value>
</injection>
</injections>
<options>
<xmlTransformerType>saxon</xmlTransformerType>
<xincludeSupported>true</xincludeSupported>
<useRelativeImageUris>true</useRelativeImageUris>
<!-- TODO Probably obsolete after the upgrade to maven-jdocbook-plugin 2.3.0 -->
<docbookVersion>1.72.0</docbookVersion>
<!-- <localeSeparator>-</localeSeparator> -->
</options>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<translation>en-US</translation>
</properties>
</project>

View file

@ -0,0 +1,59 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.docbook.org/xml/4.4/docbookx.dtd"
[
<!ENTITY License SYSTEM "modules/License.xml">
<!ENTITY Overview SYSTEM "modules/Overview.xml">
<!ENTITY Installation SYSTEM "modules/server-installation.xml">
<!ENTITY AdapterConfig SYSTEM "modules/adapter-config.xml">
<!ENTITY WildflyAdapter SYSTEM "modules/wildfly-adapter.xml">
<!ENTITY EAP6Adapter SYSTEM "modules/eap6-adapter.xml">
]>
<book>
<bookinfo>
<title>Keycloak Reference Guide</title>
<subtitle>SSO for Web Apps and REST Services</subtitle>
<releaseinfo>1.0-alpha-1-SNAPSHOT</releaseinfo>
</bookinfo>
<toc/>
<preface id="preface" revision="1">
<title>Preface</title>
<para>
In some of the example listings, what is meant to be displayed on one line does not fit
inside the available page width. These lines have been broken up. A '\' at the end of a
line means that a break has been introduced to fit in the page, with the following lines
indented. So:
<programlisting>
Let's pretend to have an extremely \
long line that \
does not fit
This one is short
</programlisting>
Is really:
<programlisting>
Let's pretend to have an extremely long line that does not fit
This one is short
</programlisting>
</para>
</preface>
&License;
&Overview;
&Installation;
<chapter>
<title>Adapters</title>
<para>
Keycloak can secure a wide variety of application types. This section defines which application
types are supported and how to configure and install them so that you can use Keycloak to secure
your applications.
</para>
&AdapterConfig;
&WildflyAdapter;
&EAP6Adapter;
</chapter>
</book>

View file

@ -0,0 +1,7 @@
<chapter id="license">
<title>License</title>
<para>RESTEasy is distributed under the ASL 2.0 license. It does not distribute any thirdparty libraries that are
GPL. It does ship thirdparty libraries licensed under
Apache ASL 2.0 and LGPL.
</para>
</chapter>

View file

@ -0,0 +1,127 @@
<chapter id="Overview">
<title>Overview</title>
<para>
Keycloak is an SSO solution for web apps and RESTful web services. It is an authentication server where users
can centrally login, logout, register, and manage their user accounts. The Keycloak admin UI can manage roles
and role mappings for any application secured by Keycloak. The Keycloak Server can also be used to perform
social logins via the user's favorite social media site i.e. Google, Facebook, Twitter etc.
</para>
<para>
</para>
<para>
Features:
<itemizedlist>
<listitem>
SSO and Single Log Out for browser applications
</listitem>
<listitem>
Social Broker. Enable Google, Facebook, Yahoo, Twitter social login with no code required.
</listitem>
<listitem>
Optional User Registration
</listitem>
<listitem>
Password and TOTP support (via Google Authenticator). Client cert auth coming soon.
</listitem>
<listitem>
OAuth Bearer token auth for REST Services
</listitem>
<listitem>
Integrated Browser App to REST Service token propagation
</listitem>
<listitem>
OAuth Bearer token auth for REST Services
</listitem>
<listitem>
OAuth 2.0 Grant requests
</listitem>
<listitem>
CORS Support
</listitem>
<listitem>
CORS Web Origin management and validation
</listitem>
<listitem>
Completely centrally managed user and role mapping metadata. Minimal configuration at the application side
</listitem>
<listitem>
Admin Console for managing users, roles, role mappings, applications, user sessions, allowed CORS web origins, and OAuth clients.
</listitem>
<listitem>
Deployable as a WAR, appliance, or on Openshift.
</listitem>
<listitem>
Supports JBoss AS7, EAP 6.x, and Wildfly applications. Plans to support Node.js, RAILS, GRAILS, and other non-Java application
</listitem>
</itemizedlist>
</para>
<section>
<title>Key Concepts in Keycloak</title>
<para>
The core concept in Keycloak is a <emphasis>Realm</emphasis>. A realm secures and manages security metadata for
for a set of users, applications, and registered oauth clients. Users can be created within a specific realm
within the Administration console. Roles (permission types) can be defined at the realm level and you can also
set up user role mappings to assign these permissions to specific users.
</para>
<para>
An <emphasis>application</emphasis> is a service that is secured by a realm. When a user browses an
application's web site, the application can redirect the user agent to the Keycloak Server and request a login.
Once a user is logged in, they can visit any other application managed by the realm and not have to re-enter
credentials. This also hold true for logging out. Roles can also be defined at the application level and
assigned to specific users. Depending on the application type, you may also be able to view and manage
user sessions from the adminstration console.
</para>
<para>
An <emphasis>oauth client</emphasis> is similar to an application in that it can request something like a login
when a user visits the site of the oauth client. The difference is that oauth clients are not immediately granted
all permissions of the user. In addition to requesting the login credentials of the user, the Keycloak Server
will also display a grant page asking the user if it is ok to grant allowed permissions to the oauth client.
</para>
</section>
<section>
<title>How Does Security Work in Keycloak?</title>
<para>
Keycloak uses <emphasis>access tokens</emphasis>. Access tokens are contains security metadata specifying the
identity of the user as well as the role mappings for that user. The format of these tokens is a Keycloak
extension to the <ulink url="http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-14">JSON Web Token</ulink> specification. Each realm has a private and public key pair
which it uses to digitally sign the access token using the <ulink url="http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-19">JSON Web Signature</ulink> specification.
Applications can verify the integrity of the digitally signed
access token using the public key of the realm. The protocols used to obtain this token is defined by the
<ulink url="http://tools.ietf.org/html/rfc6749">OAuth 2.0</ulink> specification.
</para>
<para>
The interesting thing about using these <emphasis>smart</emphasis> access tokens is that applications themselves are completely stateless
as far as security metadata goes. All the information they need about the user is contained in the token and there's
no need for them to store any security metadata locally other than the public key of the realm.
</para>
<para>
Signed access tokens can also be proprogated by REST client requests within an <literal>Authorization</literal>
header. This is great for distributed integration as applications can request a login from a client to obtain
an access token, then invoke any aggregated REST invocations to other services using that access token. So,
you have a distributed security model that is centrally managed, yet does not require a Keycloak Server hit
per request, only for the initial login.
</para>
<section>
<title>Permission Scopes</title>
<para>
Each application and oauth client are configured with a set of permission scopes. These are a set
of roles that an application or oauth client is allowed to ask permission for. Access tokens are always
granted at the request of a specific application or oauth client. This also holds true for SSO. As you visit
different sites, the application will redirect back to the Keycloak Server via the OAuth 2.0 protocol to obtain an access
token specific to that application. The role mappings contained within the token are the union
between the set of user role mappings and the permission scope of the application/oauth client. So,
access tokens are tailor made for each application/oauth client and contain only the information required
for by them.
</para>
</section>
</section>
</chapter>

View file

@ -0,0 +1,273 @@
<section id="adapter-config">
<title>General Adapter Config</title>
<para>
Each adapter supported by Keycloak can be configured by a simple JSON text file. This is what one might
look like:
</para>
<para>
<programlisting><![CDATA[{
"realm" : "demo",
"resource" : "customer-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB",
"auth-url" : "https://localhost:8443/.../realms/demo/tokens/login",
"code-url" : "https://localhost:8443/.../realms/demo/tokens/access/codes",
"ssl-not-required" : false,
"user-resource-role-mappings" : false,
"enable-cors" : true,
"cors-max-age" : 1000,
"cors-allowed-methods" : [ "POST", "PUT", "DELETE", "GET" ],
"bearer-only" : false,
"expose-token" : true,
"credentials" : {
"password" : "password"
}
"connection-pool-size" : 5,
"allo-any-hostname" : false,
"disable-trust-manager" false,
"truststore" : "path/to/truststore.jks",
"truststore-password" : "geheim",
"client-keystore" : "path/to/client-keystore.jks",
"client-keystore-password" : "geheim",
"client-key-password" : "geheim"
}]]>
</programlisting>
</para>
<para>
Some of these configuration switches may be adapter specific and some are common across all adapters.
For Java adapters you can use <literal>${...}</literal> enclosure as System property replacement.
For example <literal>${jboss.server.config.dir}</literal>. Also, you can obtain a template
for this config file from the admin console. Go to the realm and application you want a template for.
Go to the <literal>Installation</literal> tab and this will provide you with a template that includes
the public key of the realm.
</para>
<para>
Here is a description of each item:
</para>
<para>
<variablelist>
<varlistentry>
<term>realm</term>
<listitem>
<para>
Name of the realm representing the users of your distributed applications and services.
This is
<emphasis>REQUIRED.</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>resource</term>
<listitem>
<para>
Username of the application. Each application has a username that is used when the
application connects with the Keycloak server to turn an access code into an access token
(part of the OAuth 2.0 protocol). This is
<emphasis>REQUIRED.</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>realm-public-key</term>
<listitem>
<para>
PEM format of public key. You can obtain this from the administration console.
This is
<emphasis>REQUIRED.</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>auth-url</term>
<listitem>
<para>
URL of the realm's login page of the Keycloak Server's token service. You can obtain
this URL from the admin console.
This is
<emphasis>REQUIRED.</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>code-url</term>
<listitem>
<para>
URL to turn an access code into an access token. You can obtain
this URL from the admin console.
This is
<emphasis>REQUIRED.</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ssl-not-required</term>
<listitem>
<para>
Ensures that all communication to and from the Keycloak server from the adapter is over HTTPS.
This is<emphasis>OPTIONAL</emphasis>. The default value is
<emphasis>false</emphasis>
meaning
that HTTPS is required by default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>user-resource-role-mappings</term>
<listitem>
<para>
If set to true, the adapter will look inside the token for application level role mappings for
the
user. If false, it will look at the realm level for user role mappings.
This is<emphasis>OPTIONAL</emphasis>. The default value is<emphasis>false</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>enable-cors</term>
<listitem>
<para>
This enables CORS support. It will handle CORS preflight requests. It will also look into
the access token to determine valid origins.
This is<emphasis>OPTIONAL</emphasis>. The default value is<emphasis>false</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>cors-max-age</term>
<listitem>
<para>
If CORS is enabled, this sets the value of the
<literal>Access-Control-Max-Age</literal>
header.
This is<emphasis>OPTIONAL</emphasis>. If not set, this header is not returned in CORS
responses.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>cors-allowed-methods</term>
<listitem>
<para>
If CORS is enabled, this sets the value of the
<literal>Access-Control-Allow-Methods</literal>
header. This should be a JSON list of strings.
This is<emphasis>OPTIONAL</emphasis>. If not set, this header is not returned in CORS
responses.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>bearer-only</term>
<listitem>
<para>
This tells the adapter to only to bearer token authentication. That is, it will not do
OAuth 2.0 redirects, but only accept bearer tokens through the
<literal>Authorization</literal>
header.
This is<emphasis>OPTIONAL</emphasis>. The default value is<emphasis>false</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>expose-token</term>
<listitem>
<para>
If<literal>true</literal>, an authenticated browser client (via a Javascript HTTP invocation)
can obtain the signed access token via the URL<literal>root/K_QUERY_BEARER_TOKEN</literal>.
This is<emphasis>OPTIONAL</emphasis>. The default value is<emphasis>false</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>credentials</term>
<listitem>
<para>
Specify the credentials of the application. This is an object notation where the key
is the credential type and the value if the value of the credential type. Currently only
<literal>password</literal>
is supported.
This is<emphasis>REQUIRED</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>truststore</term>
<listitem>
<para>
This setting is for Java adapters. This is the file path to a Java keystore file.
Used for outgoing HTTPS communications to the Keycloak server. Client making HTTPS
requests need a way to verify the host of the server they are talking to. THis is
what the trustore does. The keystore contains one or more trusted
host certificates or certificate authorities. You can
create this truststore by extracting the public certificate of the Keycloak server's SSL
keystore.
This is
<emphasis>OPTIONAL</emphasis>
if
<literal>ssl-not-required</literal>
is
<literal>false</literal>
or
<literal>disable-trust-manager</literal>
is<literal>true</literal>. The default value is<emphasis>false</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>truststore-password</term>
<listitem>
<para>
Password for the truststore keystore.
This is
<emphasis>REQUIRED</emphasis>
if
<literal>truststore</literal>
is set.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>client-keystore</term>
<listitem>
<para>
<emphasis>Not supported yet, but we will support in future versions.</emphasis>
This setting is for Java adapters. This is the file path to a Java keystore file.
This keystore contains client certificate for two-way SSL when the adapter makes
HTTPS requests to the Keycloak server.
This is<emphasis>OPTIONAL</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>client-keystore-password</term>
<listitem>
<para>
<emphasis>Not supported yet, but we will support in future versions.</emphasis>
Password for the client keystore.
This is
<emphasis>REQUIRED</emphasis>
if
<literal>client-keystore</literal>
is set.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>client-key-password</term>
<listitem>
<para>
<emphasis>Not supported yet, but we will support in future versions.</emphasis>
Password for the client's key.
This is
<emphasis>REQUIRED</emphasis>
if
<literal>client-keystore</literal>
is set.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>

View file

@ -0,0 +1,116 @@
<section>
<title>JBoss EAP6/AS7 Adapter</title>
<section>
<title>JBoss EAP6/AS7 Adapter Adapter Installation</title>
<para>
The JBoss EAP6 Adapter is contained in the Keycloak distribution within the <literal>adapters/keycloak-eap6-adapter-dist.zip</literal>
file. Conversely, the JBoss AS 7.1.1 adapter is contained in the file <literal>adapters/keycloak-as7-adapter-dist.zip</literal>
To install it:
</para>
<para>
<programlisting>
$ cd $JBOSS_HOME
# For an EAP distro
$ unzip keycloak-eap6-adapter-dist.zip
or
# For an JBoss AS 7.1.1 distro
$ unzip keycloak-as7-adapter-dist.zip
</programlisting>
</para>
<para>
This zip file creates new JBoss Modules specific to the JBoss EAP6 Keycloak Adapter within your JBoss distro.
</para>
</section>
<section>
<title>JBoss EAP6/AS7 Adapter Configuration</title>
<para>
The JBoss EAP6 Adapter is enabled per WAR application. The adapter code is contained in a JBoss Module
so you must first create a <literal>jboss-deployment-structure.xml</literal> within your WAR's
<literal>WEB-INF</literal> directory that imports the JBoss EAP6 Keycloak Adapter.
</para>
<para>
<programlisting><![CDATA[
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.keycloak.keycloak-as7-adapter"/>
</dependencies>
</deployment>
</jboss-deployment-structure>]]>
</programlisting>
</para>
<para>
It is possible to add the adapter jars directory to your WAR, but its best to do module imports because
the adapter's dependencies may conflict with your application's.
</para>
<para>
After creating the <literal>jboss-deployment-structure.xml</literal> configuration file, you must create
a <literal>keycloak.json</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>
While you do have to specify a login-config in your WAR's <literal>web.xml</literal>, it doesn't matter what values you put there.
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[
<?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>
<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>
</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>
</security-constraint>
<!--
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint> -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>commerce</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> ]
</section>

View file

@ -0,0 +1,369 @@
<chapter id="server-installation">
<title>Installation and Configuration of Keycloak Server</title>
<para>
The Keycloak Server has two downloadable distributions.
</para>
<para>
<itemizedlist>
<listitem>
keycloak-appliance-dist-all-1.0-alpha-1-SNAPSHOT.zip
</listitem>
<listitem>
keycloak-war-dist-all-1.0-alpha-1-SNAPSHOT.zip
</listitem>
</itemizedlist>
</para>
<section>
<title>Appliance Install</title>
<para>
The
<literal>keycloak-appliance-dist-all.zip</literal>
is quite large, but contains a complete server (backed by Wildfly)
that runs out of the box. The only thing you'll have to enable and configure is SSL. Unzipping it, the
directory layout looks
something like this:
</para>
<para>
<programlisting>
keycloak-appliance-dist-all-1.0-alpha-1-SNAPSHOT/
keycloak/
bin/
standalone.sh
standalone.bat
standalone/deployments/
auth-server.war/
keycloak-ds.xml
adapters/
keycloak-as7-adapter-dist-1.0-alpha-1-SNAPSHOT.zip
keycloak-as7-adapter-dist-1.0-alpha-1-SNAPSHOT.zip
keycloak-as7-adapter-dist-1.0-alpha-1-SNAPSHOT.zip
examples/
docs/
</programlisting>
</para>
<para>
The
<literal>standalone.sh</literal>
or
<literal>standalone.bat</literal>
script is used to start the server.
After executing that, log into the admin console at<ulink
url="http://localhost:8080/auth-server/rest/saas/login">
http://localhost:8080/auth-server/rest/saas/login</ulink>.
Username:
<emphasis>admin</emphasis>
Password:<emphasis>admin</emphasis>. Keycloak with then prompt you to
enter in a new password.
</para>
</section>
<section>
<title>WAR Distribution Installation</title>
<para>
The
<literal>keycloak-war-dist-all.zip</literal>
contains
just the bits you need to install keycloak on your favorite web container. We currently only support
installing it on top of an existing JBoss AS 7.1.1, JBoss EAP 6.x, or Wildfly 8 distribution. We may in the
future provide directions on how to install it on another web container like Tomcat or Jetty. If anybody
in the community is interested in pulling this together, please contact us. Its mostly Maven pom work.
</para>
<para>
The directory structure of this distro looks like this:
</para>
<para>
<programlisting>
keycloak-war-dist-all-1.0-alpha-1-SNAPSHOT/
deployments/
auth-server.war/
keycloak-ds.xml
adapters/
keycloak-as7-adapter-dist-1.0-alpha-1-SNAPSHOT.zip
keycloak-as7-adapter-dist-1.0-alpha-1-SNAPSHOT.zip
keycloak-as7-adapter-dist-1.0-alpha-1-SNAPSHOT.zip
examples/
docs/
</programlisting>
</para>
<para>
After unzipping this file, copy the <literal>deployments/</literal> directory into to the <literal>standalone/</literal>
of your JBoss or Wildfly distro.
</para>
<para>
<programlisting>
$ cd keycloak-war-dist-all-1.0-alpha-1-SNAPSHOT
$ cp -r deployments $JBOSS_HOME/standalone
</programlisting>
</para>
<para>
After booting up the JBoss or Wildfly distro, you can then make sure it is installed properly
by logging into the admin console at<ulink
url="http://localhost:8080/auth-server/rest/saas/login">
http://localhost:8080/auth-server/rest/saas/login</ulink>.
Username:
<emphasis>admin</emphasis>
Password:<emphasis>admin</emphasis>. Keycloak with then prompt you to
enter in a new password.
</para>
</section>
<section>
<title>Configuring the Server</title>
<para>
Although the Keycloak Server is designed to run out of the box, there's some things you'll need
to configure before you go into production. Specifically:
<itemizedlist>
<listitem>
Configuring keycloak to use a production database.
</listitem>
<listitem>
Setting up SSL/HTTPS
</listitem>
<listitem>
Enforcing HTTPS connections
</listitem>
</itemizedlist>
</para>
<section>
<title>Database Configuration</title>
<para>
The datasource used to store Keycloak data is configured in the <literal>.../standalone/deployments/keycloak-ds.xml</literal>
file of your Keycloak Server installation. A good thing to delete this file and move its configuration text into the
centrally managed <literal>.../standalone/configuration/standalone.xml</literal> file. This will allow
you to manage the database connection pool from the Wildfly/JBoss adminstration console. Here's what
<literal>.../standalone/configuration/standalone.xml</literal> should look like after you've done this:
</para>
<para>
<programlisting><![CDATA[
<subsystem xmlns="urn:jboss:domain:datasources:2.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/ExampleDS"
pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<datasource jndi-name="java:jboss/datasources/KeycloakDS"
pool-name="KeycloakDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
]]>
</programlisting>
</para>
<para>
Besides moving the database config into the central <literal>standalone.xml</literal> configuration file
you might want to use a better relational database for Keycloak like Oracle or something. You might also
want to tweak the configuration settings of the datasource. Please see the <ulink url="https://docs.jboss.org/author/display/WFLY8/DataSource+configuration">Wildfly</ulink>,
<ulink url="https://docs.jboss.org/author/display/AS71/DataSource+configuration">JBoss AS7</ulink>,
or <ulink url="https://docs.jboss.org/author/display/AS71/DataSource+configuration">JBoss EAP 6.x</ulink> documentation on how to do this.
</para>
<para>
Keycloak also runs on a Hibernate/JPA backend which is configured in the
<literal>.../standalone/deployments/auth-server.war/WEB-INF/classes/META-INF/persistence.xml</literal>.
Please see the <ulink url="http://hibernate.org/orm/documentation/">Hibernate and JPA documentation</ulink> for more information on tweaking the backend datamodel.
</para>
</section>
<section>
<title>SSL/HTTPS Setup</title>
<warning>
<para>
Keycloak is not set up by default to handle SSL/HTTPS in either the
war distribution or appliance. It is highly recommended that you enable it!
</para>
</warning>
<para>
The following things need to be done
<itemizedlist>
<listitem>
Generate a self signed or third-party signed certificate and import it into a Java keystore
using <literal>keytool</literal>.
</listitem>
<listitem>
Enable JBoss or Wildfly to use this certificate and turn on SSL/HTTPS.
</listitem>
<listitem>
Configure the Keycloak Server to enforce HTTPS connections.
</listitem>
</itemizedlist>
</para>
<section>
<title>Creating the Certificate and Java Keystore</title>
<para>
In order to allow HTTPS connections, you need to obtain a self signed or third-party signed certificate
and import it into a Java keystore before you can enable HTTPS in the web container you are deploying
the Keycloak Server to.
</para>
<section>
<title>Self Signed Certificate</title>
<para>
In development, you will probably not have a third party signed certificate available to test
a Keycloak deployment so you'll need to generate a self-signed on. Generate one is very easy
to do with the <literal>keytool</literal> utility that comes with the Java jdk.
</para>
<para>
<programlisting>
$ keytool -genkey -alias localhost -keyalg RSA -keystore keycloak.jks -validity 10950
Enter keystore password: secret
Re-enter new password: secret
What is your first and last name?
[Unknown]: localhost
What is the name of your organizational unit?
[Unknown]: Keycloak
What is the name of your organization?
[Unknown]: Red Hat
What is the name of your City or Locality?
[Unknown]: Westford
What is the name of your State or Province?
[Unknown]: MA
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=localhost, OU=Keycloak, O=Test, L=Westford, ST=MA, C=US correct?
[no]: yes
</programlisting>
</para>
<para>
You should answer the <literal>What is your first and last name?</literal> question with
the DNS name of the machine you're installing the server on. For testing purposes,
<literal>localhost</literal> should be used. After executing this command, the
<literal>keycloak.jks</literal> file will be generated in the same directory as you executed
the <literal>keytool</literal> command in.
</para>
<para>
If you want a third-party signed certificate, but don't have one, you can obtain one for free
at <ulink url="http://cacert.org">cacert.org</ulink>. You'll have to do a little set up first
before doing this though.
</para>
<para>
The first thing to do is generate a Certificate Request:
<programlisting>
$ keytool -certreq -alias yourdomain -keystore keycloak.jks > keycloak.careq
</programlisting>
</para>
<para>
Where <literal>yourdomain</literal> is a DNS name for which this certificate is generated for.
Keytool generates the request:
<programlisting>
-----BEGIN NEW CERTIFICATE REQUEST-----
MIIC2jCCAcICAQAwZTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMREwDwYDVQQHEwhXZXN0Zm9y
ZDEQMA4GA1UEChMHUmVkIEhhdDEQMA4GA1UECxMHUmVkIEhhdDESMBAGA1UEAxMJbG9jYWxob3N0
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr7kck2TaavlEOGbcpi9c0rncY4HhdzmY
Ax2nZfq1eZEaIPqI5aTxwQZzzLDK9qbeAd8Ji79HzSqnRDxNYaZu7mAYhFKHgixsolE3o5Yfzbw1
29Rvy+eUVe+WZxv5oo9wolVVpdSINIMEL2LaFhtX/c1dqiqYVpfnvFshZQaIg2nL8juzZcBjj4as
H98gIS7khql/dkZKsw9NLvyxgJvp7PaXurX29fNf3ihG+oFrL22oFyV54BWWxXCKU/GPn61EGZGw
Ft2qSIGLdctpMD1aJR2bcnlhEjZKDksjQZoQ5YMXaAGkcYkG6QkgrocDE2YXDbi7GIdf9MegVJ35
2DQMpwIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUQwlZJBA+fjiDdiVzaO9vrE/i
n2swDQYJKoZIhvcNAQELBQADggEBAC5FRvMkhal3q86tHPBYWBuTtmcSjs4qUm6V6f63frhveWHf
PzRrI1xH272XUIeBk0gtzWo0nNZnf0mMCtUBbHhhDcG82xolikfqibZijoQZCiGiedVjHJFtniDQ
9bMDUOXEMQ7gHZg5q6mJfNG9MbMpQaUVEEFvfGEQQxbiFK7hRWU8S23/d80e8nExgQxdJWJ6vd0X
MzzFK6j4Dj55bJVuM7GFmfdNC52pNOD5vYe47Aqh8oajHX9XTycVtPXl45rrWAH33ftbrS8SrZ2S
vqIFQeuLL3BaHwpl3t7j2lMWcK1p80laAxEASib/fAwrRHpLHBXRcq6uALUOZl4Alt8=
-----END NEW CERTIFICATE REQUEST-----
</programlisting>
</para>
<para>
Send this ca request to your CA. The CA will issue you a signed certificate and send it to you.
Before you import your new cert, you must obtain and import the root certificate of the CA.
You can download the cert from CA (ie.: root.crt) and import as follows:
<programlisting>
$ keytool -import -keystore keycloak.jks -file root.crt -alias root
</programlisting>
</para>
<para>
Last step is import your new CA generated certificate to your keystore:
<programlisting>
$ keytool -import -alias yourdomain -keystore keycloak.jks -file your-certificate.cer
</programlisting>
</para>
</section>
</section>
<section>
<title>Installing the keystore</title>
<para>
Now that you have a Java keystore with the appropriate certificates, you need to configure your
JBoss or Wildfly installation to use it. First step is to move the keystore file to a directory
you can reference in configuration. I like to put it in <literal>standalone/configuration</literal>.
Then you need to edit <literal>standalone/configuration/standalone.xml</literal> to enable SSL/HTTPS.
</para>
<para>
<programlisting><![CDATA[]
<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" redirect-port="443" />
<connector name="https" scheme="https" protocol="HTTP/1.1" socket-binding="https"
enable-lookups="false" secure="true">
<ssl name="localhost-ssl" password="secret" protocol="TLSv1"
key-alias="localhost" certificate-key-file="${jboss.server.config.dir}/foo.keystore" />
</connector>
...
</subsystem>
]]>
</programlisting>
</para>
<para>
Check the <ulink url="https://docs.jboss.org/author/display/WFLY8/SSL+setup+guide">Wildfly</ulink>
or <ulink url="https://docs.jboss.org/author/display/AS71/SSL+setup+guide">JBoss</ulink> documentation for more information on fine tuning the socket connections.
</para>
</section>
<section>
<title>Enforce HTTPS For Server Connections</title>
<para>
Servlet containers can force browsers and other HTTP clients to use HTTPS. You have to configure this in
<literal>.../standalone/deployments/auth-server.war/WEB-INF/web.xml</literal>. All you have to do is
uncomment out the security constraint.
</para>
<para>
<programlisting><![CDATA[]
<web-app>
...
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>
]]>
</programlisting>
</para>
</section>
<section>
<title>Enforce HTTPS at Realm Level</title>
<para>
In Keycloak, each realm has an "Require SSL" switch that you should turn on. Log into the
adminstration console and set this switch for each realm that Keycloak manages. This switch is on
the <literal>Settings>>General</literal> page. While this switch does do similar checks as the security
constraint in <literal>web.xml</literal>, it will also force applications and oauth clients to only
register HTTPS based redirect URLs.
</para>
</section>
</section>
</section>
</chapter>

View file

@ -0,0 +1,107 @@
<section>
<title>Wildfly 8 Adapter</title>
<section>
<title>Wildfly Adapter Installation</title>
<para>
The Wildfly 8 Adapter is contained in the Keycloak distribution within the <literal>adapters/keycloak-wildfly-adapter-dist.zip</literal>
file. To install it:
</para>
<para>
<programlisting>
$ cd $WILDFLY_HOME
$ unzip keycloak-wildfly-adapter-dist.zip
</programlisting>
</para>
<para>
This zip file creates new JBoss Modules specific to the Wildfly Keycloak Adapter within your Wildfly distro.
</para>
</section>
<section>
<title>Wildfly 8 Adapter Configuration</title>
<para>
The Wildfly 8 Adapter is enabled per WAR application. The adapter code is contained in a JBoss Module
so you must first create a <literal>jboss-deployment-structure.xml</literal> within your WAR's
<literal>WEB-INF</literal> directory that imports the Wildfly Keycloak Adapter.
</para>
<para>
<programlisting><![CDATA[
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.keycloak.keycloak-undertow-adapter" services="import"/>
</dependencies>
</deployment>
</jboss-deployment-structure>]]>
</programlisting>
</para>
<para>
It is possible to add the adapter jars directory to your WAR, but its best to do module imports because
the adapter's dependencies may conflict with your application's.
</para>
<para>
After creating the <literal>jboss-deployment-structure.xml</literal> configuration file, you must create
a <literal>keycloak.json</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>
Finally you must set the <literal>auth-method</literal> to <literal>KEYCLOAK</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>
</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>
</security-constraint>
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>KEYCLOAK</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> ]
</section>