419 lines
No EOL
18 KiB
XML
Executable file
419 lines
No EOL
18 KiB
XML
Executable file
<!--
|
|
~ 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.
|
|
-->
|
|
|
|
<chapter id="proxy">
|
|
<title>Keycloak Security Proxy</title>
|
|
<para>
|
|
Keycloak has an HTTP(S) proxy that you can put in front of web applications and services where it is not possible
|
|
to install the keycloak adapter. You can set up URL filters so that certain URLs are secured either by browser login
|
|
and/or bearer token authentication. You can also define role constraints for URL patterns within your applications.
|
|
</para>
|
|
<section>
|
|
<title>Proxy Install and Run</title>
|
|
<para>Download the keycloak proxy distribution from the Keycloak download pages and unzip it.
|
|
<programlisting>
|
|
$ unzip keycloak-proxy-dist.zip
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
To run it you must have a proxy config file (which we'll discuss in a moment).
|
|
<programlisting>
|
|
$ java -jar bin/launcher.jar [your-config.json]
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
If you do not specify a path to the proxy config file, the launcher will look in the current working directory
|
|
for the file named <literal>proxy.json</literal>
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Proxy Configuration</title>
|
|
<para>
|
|
Here's an example configuration file.
|
|
<programlisting><![CDATA[
|
|
{
|
|
"target-url": "http://localhost:8082",
|
|
"send-access-token": true,
|
|
"bind-address": "localhost",
|
|
"http-port": "8080",
|
|
"https-port": "8443",
|
|
"keystore": "classpath:ssl.jks",
|
|
"keystore-password": "password",
|
|
"key-password": "password",
|
|
"applications": [
|
|
{
|
|
"base-path": "/customer-portal",
|
|
"error-page": "/error.html",
|
|
"adapter-config": {
|
|
"realm": "demo",
|
|
"resource": "customer-portal",
|
|
"realm-public-key": "MIGfMA0GCSqGSIb",
|
|
"auth-server-url": "http://localhost:8081/auth",
|
|
"ssl-required" : "external",
|
|
"principal-attribute": "name",
|
|
"credentials": {
|
|
"secret": "password"
|
|
}
|
|
}
|
|
,
|
|
"constraints": [
|
|
{
|
|
"pattern": "/users/*",
|
|
"roles-allowed": [
|
|
"user"
|
|
]
|
|
},
|
|
{
|
|
"pattern": "/admins/*",
|
|
"roles-allowed": [
|
|
"admin"
|
|
]
|
|
},
|
|
{
|
|
"pattern": "/users/permit",
|
|
"permit": true
|
|
},
|
|
{
|
|
"pattern": "/users/deny",
|
|
"deny": true
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}]]>
|
|
</programlisting>
|
|
</para>
|
|
<section>
|
|
<title>Basic Config</title>
|
|
<para>
|
|
The basic configuration options for the server are as follows:
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>target-url</term>
|
|
<listitem>
|
|
<para>
|
|
The URL this server is proxying <emphasis>REQUIRED.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>send-access-token</term>
|
|
<listitem>
|
|
<para>
|
|
Boolean flag. If true, this will send the access token via the KEYCLOAK_ACCESS_TOKEN header to the
|
|
proxied server. <emphasis>OPTIONAL.</emphasis>. Default is false.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>bind-address</term>
|
|
<listitem>
|
|
<para>
|
|
DNS name or IP address to bind the proxy server's sockets to.
|
|
<emphasis>OPTIONAL.</emphasis>. The default value is <emphasis>localhost</emphasis>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>http-port</term>
|
|
<listitem>
|
|
<para>
|
|
Port to listen for HTTP requests. If you do not specify this value, then the proxy will
|
|
not listen for regular HTTP requests.
|
|
<emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>https-port</term>
|
|
<listitem>
|
|
<para>
|
|
Port to listen for HTTPS requests. If you do not specify this value, then the proxy will
|
|
not listen for HTTPS requests.
|
|
<emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>keystore</term>
|
|
<listitem>
|
|
<para>
|
|
Path to a Java keystore file that contains private key and certificate for the server to be
|
|
able to handle HTTPS requests. Can be a file path, or, if you prefix it with <literal>classpath:</literal>
|
|
it will look for this file in the classpath.
|
|
<emphasis>OPTIONAL.</emphasis>. If you have enabled HTTPS, but have not defined a keystore, the proxy
|
|
will auto-generate a self-signed certificate and use that.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>buffer-size</term>
|
|
<listitem>
|
|
<para>
|
|
HTTP server socket buffer size. Usually the default is good enough. <emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>buffers-per-region</term>
|
|
<listitem>
|
|
<para>
|
|
HTTP server socket buffers per region. Usually the default is good enough. <emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>io-threads</term>
|
|
<listitem>
|
|
<para>
|
|
Number of threads to handle IO. Usually default is good enough. <emphasis>OPTIONAL.</emphasis>.
|
|
The default is the number of available processors * 2.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>worker-threads</term>
|
|
<listitem>
|
|
<para>
|
|
Number of threads to handle requests. Usually the default is good enough. <emphasis>OPTIONAL.</emphasis>.
|
|
The default is the number of available processors * 16.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Application Config</title>
|
|
<para>
|
|
Next under the <literal>applications</literal> array attribute, you can define one or more applications per host you are proxying.
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>base-path</term>
|
|
<listitem>
|
|
<para>
|
|
The base context root for the application. Must start with '/' <emphasis>REQUIRED.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>error-page</term>
|
|
<listitem>
|
|
<para>
|
|
If the proxy has an error, it will display the target application's error page relative URL <emphasis>OPTIONAL.</emphasis>.
|
|
This is a relative path to the base-path. In the example above it would be <literal>/customer-portal/error.html</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>adapter-config</term>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>REQUIRED.</emphasis>. Same configuration as any other keycloak adapter. See <link linkend='adapter-config'>Adapter Config</link>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
<section>
|
|
<title>Constraint Config</title>
|
|
<para>
|
|
Next under each application you can define one or more constraints in the <literal>constraints</literal> array attribute.
|
|
A constraint defines a URL pattern relative to the base-path. You can deny, permit, or require authentication for
|
|
a specific URL pattern. You can specify roles allowed for that path as well. More specific constraints will take
|
|
precedence over more general ones.
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>pattern</term>
|
|
<listitem>
|
|
<para>
|
|
URL pattern to match relative to the base-path of the application. Must start with '/' <emphasis>REQUIRED.</emphasis>.
|
|
You may only have one wildcard and it must come at the end of the pattern. Valid <literal>/foo/bar/*</literal> and <literal>/foo/*.txt</literal>
|
|
Not valid: <literal>/*/foo/*</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>roles-allowed</term>
|
|
<listitem>
|
|
<para>
|
|
Array of strings of roles allowed to access this url pattern. <emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>methods</term>
|
|
<listitem>
|
|
<para>
|
|
Array of strings of HTTP methods that will exclusively match this pattern and HTTP request. <emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>excluded-methods</term>
|
|
<listitem>
|
|
<para>
|
|
Array of strings of HTTP methods that will be ignored when match this pattern. <emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>deny</term>
|
|
<listitem>
|
|
<para>
|
|
Deny all access to this URL pattern. <emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>permit</term>
|
|
<listitem>
|
|
<para>
|
|
Permit all access without requiring authentication or a role mapping. <emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>permit-and-inject</term>
|
|
<listitem>
|
|
<para>
|
|
Permit all access, but inject the headers, if user is already authenticated.<emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>authenticate</term>
|
|
<listitem>
|
|
<para>
|
|
Require authentication for this pattern, but no role mapping. <emphasis>OPTIONAL.</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section>
|
|
<title>Header Names Config</title>
|
|
<para>
|
|
Next under the list of applications you can override the defaults for the names of the header fields injected by the proxy (see Keycloak Identity Headers).
|
|
This mapping is optional.
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>keycloak-subject</term>
|
|
<listitem>
|
|
<para>
|
|
e.g. MYAPP_USER_ID
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>keycloak-username</term>
|
|
<listitem>
|
|
<para>
|
|
e.g. MYAPP_USER_NAME
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>keycloak-email</term>
|
|
<listitem>
|
|
<para>
|
|
e.g. MYAPP_USER_EMAIL
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>keycloak-name</term>
|
|
<listitem>
|
|
<para>
|
|
e.g. MYAPP_USER_ID
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>keycloak-access-token</term>
|
|
<listitem>
|
|
<para>
|
|
e.g. MYAPP_ACCESS_TOKEN
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section>
|
|
<title>Keycloak Identity Headers</title>
|
|
<para>
|
|
When forwarding requests to the proxied server, Keycloak Proxy will set some additional headers with values from the
|
|
OIDC identity token it received for authentication.
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>KEYCLOAK-SUBJECT</term>
|
|
<listitem>
|
|
<para>
|
|
User id. Corresponds to JWT <literal>sub</literal> and will be the user id Keycloak uses to store
|
|
this user.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>KEYCLOAK-USERNAME</term>
|
|
<listitem>
|
|
<para>
|
|
Username. Corresponds to JWT <literal>preferred_username</literal>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>KEYCLOAK-EMAIL</term>
|
|
<listitem>
|
|
<para>
|
|
Email address of user if set.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>KEYCLOAK-NAME</term>
|
|
<listitem>
|
|
<para>
|
|
Full name of user if set.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>KEYCLOAK-ACCESS-TOKEN</term>
|
|
<listitem>
|
|
<para>
|
|
Send the access token in this header if the proxy was configured to send it. This token can
|
|
be used to make bearer token requests.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
Header field names can be configured using a map of <literal>header-names</literal> in configuration file:
|
|
<programlisting><![CDATA[
|
|
{
|
|
"header-names" {
|
|
"keycloak-subject": "MY-SUBJECT"
|
|
}
|
|
}
|
|
]]></programlisting>
|
|
</para>
|
|
</section>
|
|
</chapter> |