Merge remote-tracking branch 'tmp/master'
7
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
||||||
node_modules
|
|
||||||
_book
|
_book
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
|
||||||
# Intellij
|
# Intellij
|
||||||
###################
|
###################
|
||||||
|
@ -48,3 +49,7 @@ catalog.xml
|
||||||
#########
|
#########
|
||||||
target
|
target
|
||||||
|
|
||||||
|
# Test build
|
||||||
|
############
|
||||||
|
build/
|
||||||
|
|
||||||
|
|
9
server_installation/README.adoc
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
= Server Installation and Configuration Guide
|
||||||
|
|
||||||
|
image:images/keycloak_logo.png[alt="Keycloak"]
|
||||||
|
|
||||||
|
{{book.project.name}} {{book.project.version}}
|
||||||
|
|
||||||
|
http://www.keycloak.org
|
||||||
|
|
52
server_installation/SUMMARY.adoc
Executable file
|
@ -0,0 +1,52 @@
|
||||||
|
= {{book.title}}
|
||||||
|
|
||||||
|
. link:topics/overview.adoc[Overview]
|
||||||
|
.. link:topics/overview/recommended-reading.adoc[Recommended Reading]
|
||||||
|
. link:topics/installation.adoc[Installation]
|
||||||
|
.. link:topics/installation/system-requirements.adoc[System Requirements]
|
||||||
|
{% if book.community %}
|
||||||
|
.. link:topics/installation/distribution-files-community.adoc[Installing Distribution Files]
|
||||||
|
{% endif %}
|
||||||
|
{% if book.product %}
|
||||||
|
.. link:topics/installation/distribution-files-product.adoc[Installing Distribution Files]
|
||||||
|
{% endif %}
|
||||||
|
.. link:topics/installation/directory-structure.adoc[Distribution Directory Structure]
|
||||||
|
. link:topics/operating-mode.adoc[Choosing an Operating Mode]
|
||||||
|
.. link:topics/operating-mode/standalone.adoc[Standalone Mode]
|
||||||
|
.. link:topics/operating-mode/standalone-ha.adoc[Standalone Clustered Mode]
|
||||||
|
.. link:topics/operating-mode/domain.adoc[Domain Clustered Mode]
|
||||||
|
. link:topics/config-subsystem.adoc[Managing Configuration]
|
||||||
|
.. link:topics/config-subsystem/configure-spi-providers.adoc[Configure SPI Providers]
|
||||||
|
.. link:topics/config-subsystem/start-cli.adoc[Start CLI]
|
||||||
|
.. link:topics/config-subsystem/cli-recipes.adoc[CLI Recipes]
|
||||||
|
. link:topics/profiles.adoc[Profiles]
|
||||||
|
. link:topics/database.adoc[Relational Database Setup]
|
||||||
|
.. link:topics/database/checklist.adoc[Setup Checklist]
|
||||||
|
.. link:topics/database/jdbc.adoc[JDBC Setup]
|
||||||
|
.. link:topics/database/datasource.adoc[Datasource Setup]
|
||||||
|
.. link:topics/database/hibernate.adoc[Database Configuration]
|
||||||
|
.. link:topics/database/unicode-considerations.adoc[Unicode considerations]
|
||||||
|
{% if book.community %}
|
||||||
|
. link:topics/mongo.adoc[Mongo DB Setup]
|
||||||
|
{% endif %}
|
||||||
|
. link:topics/network.adoc[Network Setup]
|
||||||
|
.. link:topics/network/bind-address.adoc[Bind Addresses]
|
||||||
|
.. link:topics/network/ports.adoc[Socket Port Bindings]
|
||||||
|
.. link:topics/network/https.adoc[HTTPS/SSL Setup]
|
||||||
|
.. link:topics/network/outgoing.adoc[Outgoing HTTP Requests]
|
||||||
|
. link:topics/clustering.adoc[Clustering]
|
||||||
|
.. link:topics/clustering/recommended.adoc[Recommended Network Architecture]
|
||||||
|
.. link:topics/clustering/example.adoc[Cluster Example]
|
||||||
|
.. link:topics/clustering/load-balancer.adoc[Setting Up a Load Balancer or Proxy]
|
||||||
|
.. link:topics/clustering/multicast.adoc[Multicast Network Setup]
|
||||||
|
.. link:topics/clustering/serialized.adoc[Serialized Cluster Startup]
|
||||||
|
.. link:topics/clustering/booting.adoc[Booting the Cluster]
|
||||||
|
.. link:topics/clustering/troubleshooting.adoc[Troubleshooting]
|
||||||
|
. link:topics/cache.adoc[Server Cache Configuration]
|
||||||
|
.. link:topics/cache/eviction.adoc[Eviction Policy and Max Entries]
|
||||||
|
.. link:topics/cache/replication.adoc[Replication and Failover]
|
||||||
|
.. link:topics/cache/disable.adoc[Disabling Caching]
|
||||||
|
.. link:topics/cache/clear.adoc[Clearing Caches at Runtime]
|
||||||
|
{% if book.community %}
|
||||||
|
. link:topics/proxy.adoc[Keycloak Security Proxy]
|
||||||
|
{% endif %}
|
67
server_installation/book-product.json
Executable file
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
"gitbook": "2.x.x",
|
||||||
|
"structure": {
|
||||||
|
"readme": "README.adoc"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"toggle-chapters",
|
||||||
|
"ungrey",
|
||||||
|
"splitter"
|
||||||
|
],
|
||||||
|
"variables": {
|
||||||
|
"title": "Server Installation and Configuration Guide",
|
||||||
|
"project": {
|
||||||
|
"name": "Red Hat Single Sign-On",
|
||||||
|
"version": "7.1.0",
|
||||||
|
"doc_base_url": "https://access.redhat.com/documentation/en/red-hat-single-sign-on/",
|
||||||
|
"doc_info_version_url": "7.1-Beta"
|
||||||
|
},
|
||||||
|
"community": false,
|
||||||
|
"product": true,
|
||||||
|
"images": "rhsso-images",
|
||||||
|
"appserver": {
|
||||||
|
"name": "JBoss EAP",
|
||||||
|
"version": "7.0",
|
||||||
|
"admindoc": {
|
||||||
|
"name": "JBoss EAP Configuration Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/7.0/single/configuration-guide/configuration-guide"
|
||||||
|
},
|
||||||
|
"datasource": {
|
||||||
|
"name": "JBoss EAP Configuration Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/7.0/single/configuration-guide/#datasource_management"
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"name": "JBoss EAP Configuration Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/7.0/single/configuration-guide/#network_and_port_configuration"
|
||||||
|
},
|
||||||
|
"socket": {
|
||||||
|
"name": "JBoss EAP Configuration Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/7.0/single/configuration-guide/#network_and_port_configuration"
|
||||||
|
},
|
||||||
|
"loadbalancer": {
|
||||||
|
"name": "JBoss EAP Configuration Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/7.0/single/configuration-guide/#configuring_high_availability"
|
||||||
|
},
|
||||||
|
"jgroups": {
|
||||||
|
"name": "JBoss EAP Configuration Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/7.0/single/configuration-guide/#cluster_communication_jgroups"
|
||||||
|
},
|
||||||
|
"caching": {
|
||||||
|
"name": "JBoss EAP Configuration Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/7.0/single/configuration-guide/#infinispan"
|
||||||
|
},
|
||||||
|
"jpa": {
|
||||||
|
"name": "JBoss EAP Development Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/7.0/single/development-guide/#hibernate"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"developerguide": {
|
||||||
|
"name": "Server Developer Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-single-sign-on/7.1-Beta/server-developer-guide/"
|
||||||
|
},
|
||||||
|
"adminguide": {
|
||||||
|
"name": "Server Administration Guide",
|
||||||
|
"link": "https://access.redhat.com/documentation/en/red-hat-single-sign-on/7.1-Beta/server-administration-guide/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
server_installation/book.json
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
{
|
||||||
|
"gitbook": "2.x.x",
|
||||||
|
"structure": {
|
||||||
|
"readme": "README.adoc"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"toggle-chapters",
|
||||||
|
"ungrey",
|
||||||
|
"splitter"
|
||||||
|
],
|
||||||
|
"variables": {
|
||||||
|
"title": "Server Installation and Configuration Guide",
|
||||||
|
"project": {
|
||||||
|
"name": "Keycloak",
|
||||||
|
"version": "SNAPSHOT"
|
||||||
|
},
|
||||||
|
"community": true,
|
||||||
|
"product": false,
|
||||||
|
"images": "keycloak-images",
|
||||||
|
"appserver": {
|
||||||
|
"name": "Wildfly",
|
||||||
|
"version": "10",
|
||||||
|
"admindoc": {
|
||||||
|
"name": "WildFly 10 Documentation",
|
||||||
|
"link": "https://docs.jboss.org/author/display/WFLY10/Documentation"
|
||||||
|
},
|
||||||
|
"datasource": {
|
||||||
|
"name": "WildFly 10 Documentation",
|
||||||
|
"link": "https://docs.jboss.org/author/display/WFLY10/DataSource+configuration"
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"name": "WildFly 10 Documentation",
|
||||||
|
"link": "https://docs.jboss.org/author/display/WFLY10/Interfaces+and+ports"
|
||||||
|
},
|
||||||
|
"socket": {
|
||||||
|
"name": "WildFly 10 Documentation",
|
||||||
|
"link": "https://docs.jboss.org/author/display/WFLY10/Interfaces+and+ports"
|
||||||
|
},
|
||||||
|
"loadbalancer": {
|
||||||
|
"name": "WildFly 10 Documentation",
|
||||||
|
"link": "https://docs.jboss.org/author/display/WFLY10/High+Availability+Guide"
|
||||||
|
},
|
||||||
|
"jgroups": {
|
||||||
|
"name": "WildFly 10 Documentation",
|
||||||
|
"link": "https://docs.jboss.org/author/display/WFLY10/JGroups+Subsystem"
|
||||||
|
},
|
||||||
|
"caching": {
|
||||||
|
"name": "WildFly 10 Documentation",
|
||||||
|
"link": "https://docs.jboss.org/author/display/WFLY10/Infinispan+Subsystem"
|
||||||
|
},
|
||||||
|
"jpa": {
|
||||||
|
"name": "WildFly 10 Documentation",
|
||||||
|
"link": "https://docs.jboss.org/author/display/WFLY10/JPA+Reference+Guide#JPAReferenceGuide-Hibernateproperties"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"developerguide": {
|
||||||
|
"name": "Server Developer Guide",
|
||||||
|
"link": "https://keycloak.gitbooks.io/server-developer-guide/content/"
|
||||||
|
},
|
||||||
|
"adminguide": {
|
||||||
|
"name": "Server Administration Guide",
|
||||||
|
"link": "https://keycloak.gitbooks.io/server-adminstration-guide/content/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
server_installation/build.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd $(readlink -f `dirname $0`)
|
||||||
|
|
||||||
|
python gitlab-conversion.py
|
||||||
|
cd target
|
||||||
|
asciidoctor master.adoc
|
69
server_installation/buildGuide.sh
Executable file
|
@ -0,0 +1,69 @@
|
||||||
|
# Build the guide
|
||||||
|
|
||||||
|
# Find the directory name and full path
|
||||||
|
CURRENT_GUIDE=${PWD##*/}
|
||||||
|
CURRENT_DIRECTORY=$(pwd)
|
||||||
|
|
||||||
|
usage(){
|
||||||
|
cat <<EOM
|
||||||
|
USAGE: $0 [OPTION]
|
||||||
|
|
||||||
|
DESCRIPTION: Build the documentation in this directory.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-h Print help.
|
||||||
|
|
||||||
|
EOM
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts "ht:" c
|
||||||
|
do
|
||||||
|
case "$c" in
|
||||||
|
h) usage
|
||||||
|
exit 1;;
|
||||||
|
\?) echo "Unknown option: -$OPTARG." >&2
|
||||||
|
usage
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -d target ]; then
|
||||||
|
echo "You must run 'python gitlab-conversion.py' to convert the content before you run this script."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove the html and build directories and then recreate the html/images/ directory
|
||||||
|
if [ -d target/html ]; then
|
||||||
|
- rm -r target/html/
|
||||||
|
fi
|
||||||
|
if [ -d target/html ]; then
|
||||||
|
rm -r target/html/
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p html
|
||||||
|
cp -r target/images/ target/html/
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "********************************************"
|
||||||
|
echo " Building $CURRENT_GUIDE "
|
||||||
|
echo "********************************************"
|
||||||
|
echo ""
|
||||||
|
echo "Building an asciidoctor version of the guide"
|
||||||
|
asciidoctor -t -dbook -a toc -o target/html/$CURRENT_GUIDE.html target/master.adoc
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Building a ccutil version of the guide"
|
||||||
|
ccutil compile --lang en_US --format html-single --main-file target/master.adoc
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
echo "View the asciidoctor build here: " file://$CURRENT_DIRECTORY/target/html/$CURRENT_GUIDE.html
|
||||||
|
|
||||||
|
if [ -d $CURRENT_DIRECTORY/build/tmp/en-US/html-single/ ]; then
|
||||||
|
echo "View the ccutil build here: " file://$CURRENT_DIRECTORY/build/tmp/en-US/html-single/index.html
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}Build using ccutil failed!"
|
||||||
|
echo -e "${BLACK}See the log above for details."
|
||||||
|
exit 1
|
||||||
|
fi
|
113
server_installation/gitlab-conversion.py
Executable file
|
@ -0,0 +1,113 @@
|
||||||
|
import sys, os, re, json, shutil, errno
|
||||||
|
|
||||||
|
def transform(root, f, targetdir):
|
||||||
|
full = os.path.join(root, f)
|
||||||
|
input = open(full, 'r').read()
|
||||||
|
dir = os.path.join(targetdir, root)
|
||||||
|
if not os.path.exists(dir):
|
||||||
|
os.makedirs(dir)
|
||||||
|
output = open(os.path.join(dir, f), 'w')
|
||||||
|
input = applyTransformation(input)
|
||||||
|
output.write(input)
|
||||||
|
|
||||||
|
|
||||||
|
def applyTransformation(input):
|
||||||
|
for variable in re.findall(r"\{\{(.*?)\}\}", input):
|
||||||
|
tmp = variable.replace('.', '_')
|
||||||
|
input = input.replace(variable, tmp)
|
||||||
|
input = input.replace('{{', '{').replace('}}', '}')
|
||||||
|
input = re.sub(r"<<fake.+#", "<<", input)
|
||||||
|
for variable in re.findall(r"[ ]*{% if (.*?) %}", input):
|
||||||
|
tmp = variable.replace('.', '_')
|
||||||
|
input = input.replace(variable, tmp)
|
||||||
|
exp = re.compile("[ ]*{% if (.*?) %}(.*?)[ ]*{% endif %}", re.DOTALL)
|
||||||
|
input = re.sub(exp, "ifeval::[{\g<1>}==true]\g<2>endif::[]", input)
|
||||||
|
input = re.sub(r"image:(\.\./)*", "image:", input)
|
||||||
|
input = re.sub(r"image::(\.\./)*", "image::", input)
|
||||||
|
return input
|
||||||
|
|
||||||
|
|
||||||
|
indir = 'topics'
|
||||||
|
targetdir = 'target'
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
targetdir = sys.argv[1]
|
||||||
|
|
||||||
|
if os.path.exists(targetdir):
|
||||||
|
shutil.rmtree(targetdir)
|
||||||
|
|
||||||
|
if os.path.isdir('images'):
|
||||||
|
shutil.copytree('images',os.path.join(targetdir, 'images'))
|
||||||
|
if os.path.isdir('keycloak-images'):
|
||||||
|
shutil.copytree('keycloak-images',os.path.join(targetdir, 'keycloak-images'))
|
||||||
|
if os.path.isdir('rhsso-images'):
|
||||||
|
shutil.copytree('rhsso-images',os.path.join(targetdir, 'rhsso-images'))
|
||||||
|
|
||||||
|
shutil.copyfile('metadata.ini', os.path.join(targetdir, 'metadata.ini'));
|
||||||
|
shutil.copyfile('master-docinfo.xml', os.path.join(targetdir, 'master-docinfo.xml'));
|
||||||
|
|
||||||
|
tmp = os.path.join(targetdir, 'topics')
|
||||||
|
if not os.path.exists(tmp):
|
||||||
|
os.makedirs(tmp)
|
||||||
|
|
||||||
|
# transform files
|
||||||
|
for root, dirs, filenames in os.walk(indir):
|
||||||
|
for f in filenames:
|
||||||
|
transform(root,f,targetdir)
|
||||||
|
|
||||||
|
# Create master.doc includes
|
||||||
|
input = open('SUMMARY.adoc', 'r').read()
|
||||||
|
output = open(os.path.join(targetdir, 'master.adoc'), 'w')
|
||||||
|
|
||||||
|
output.write("""
|
||||||
|
:toc:
|
||||||
|
:toclevels: 3
|
||||||
|
:numbered:
|
||||||
|
|
||||||
|
include::document-attributes.adoc[]
|
||||||
|
""")
|
||||||
|
|
||||||
|
input = re.sub(r"[ ]*\.+\s*link:(.*)\[(.*)\]", "include::\g<1>[]", input)
|
||||||
|
input = applyTransformation(input)
|
||||||
|
output.write(input)
|
||||||
|
|
||||||
|
# parse book-product.json file and create document attributes
|
||||||
|
with open('book-product.json') as data_file:
|
||||||
|
data = json.load(data_file)
|
||||||
|
|
||||||
|
variables = data['variables']
|
||||||
|
|
||||||
|
def makeAttributes(variables, variable, list):
|
||||||
|
for i in variables.keys():
|
||||||
|
if variable is None:
|
||||||
|
tmp = i
|
||||||
|
else:
|
||||||
|
tmp = variable + '_' + i
|
||||||
|
if isinstance(variables[i],dict):
|
||||||
|
makeAttributes(variables[i], tmp, list)
|
||||||
|
elif isinstance(variables[i],bool):
|
||||||
|
boolval = 'false'
|
||||||
|
if variables[i]:
|
||||||
|
boolval = 'true'
|
||||||
|
list.append({tmp: boolval})
|
||||||
|
else:
|
||||||
|
list.append({tmp: str(variables[i])})
|
||||||
|
|
||||||
|
|
||||||
|
attributeList = []
|
||||||
|
makeAttributes(variables, None, attributeList)
|
||||||
|
|
||||||
|
output = open(os.path.join(targetdir, 'document-attributes.adoc'), 'w')
|
||||||
|
for attribute in attributeList:
|
||||||
|
for k in attribute.keys():
|
||||||
|
output.write(':book_' + k + ": " + attribute[k] + "\n")
|
||||||
|
|
||||||
|
print "Transformation complete!"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
server_installation/images/add-provider-dialog.png
Executable file
After Width: | Height: | Size: 88 KiB |
BIN
server_installation/images/add-provider-select.png
Executable file
After Width: | Height: | Size: 59 KiB |
BIN
server_installation/images/cli-gui.png
Normal file
After Width: | Height: | Size: 155 KiB |
BIN
server_installation/images/domain-mode.png
Executable file
After Width: | Height: | Size: 103 KiB |
BIN
server_installation/images/domain.png
Executable file
After Width: | Height: | Size: 68 KiB |
BIN
server_installation/images/email-simple-example.png
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
server_installation/images/identity_broker_flow.png
Executable file
After Width: | Height: | Size: 21 KiB |
BIN
server_installation/images/keycloak_logo.png
Executable file
After Width: | Height: | Size: 18 KiB |
BIN
server_installation/images/update-server-config-dialog.png
Executable file
After Width: | Height: | Size: 66 KiB |
BIN
server_installation/images/update-server-config-select.png
Executable file
After Width: | Height: | Size: 80 KiB |
BIN
server_installation/keycloak-images/db-module.png
Executable file
After Width: | Height: | Size: 80 KiB |
BIN
server_installation/keycloak-images/domain-boot-files.png
Executable file
After Width: | Height: | Size: 56 KiB |
BIN
server_installation/keycloak-images/domain-file.png
Executable file
After Width: | Height: | Size: 67 KiB |
BIN
server_installation/keycloak-images/domain-json-config.png
Executable file
After Width: | Height: | Size: 7.2 KiB |
BIN
server_installation/keycloak-images/domain-server-dir.png
Executable file
After Width: | Height: | Size: 57 KiB |
BIN
server_installation/keycloak-images/files.png
Executable file
After Width: | Height: | Size: 38 KiB |
BIN
server_installation/keycloak-images/host-files.png
Executable file
After Width: | Height: | Size: 66 KiB |
BIN
server_installation/keycloak-images/standalone-boot-files.png
Executable file
After Width: | Height: | Size: 59 KiB |
BIN
server_installation/keycloak-images/standalone-config-file.png
Executable file
After Width: | Height: | Size: 81 KiB |
BIN
server_installation/keycloak-images/standalone-ha-config-file.png
Executable file
After Width: | Height: | Size: 81 KiB |
BIN
server_installation/keycloak-images/standalone-json-config-file.png
Executable file
After Width: | Height: | Size: 9.3 KiB |
12
server_installation/master-docinfo.xml
Executable file
|
@ -0,0 +1,12 @@
|
||||||
|
<productname>{book_project_name}</productname>
|
||||||
|
<productnumber>{book_project_doc_info_version_url}</productnumber>
|
||||||
|
<subtitle>For Use with {book_project_name} {book_project_doc_info_version_url}</subtitle>
|
||||||
|
<title>{book_title}</title>
|
||||||
|
<release>{book_project_doc_info_version_url}</release>
|
||||||
|
<abstract>
|
||||||
|
<para>This guide consists of information to install and configure {book_project_name} {book_project_doc_info_version_url}</para>
|
||||||
|
</abstract>
|
||||||
|
<authorgroup>
|
||||||
|
<orgname>Red Hat Customer Content Services</orgname>
|
||||||
|
</authorgroup>
|
||||||
|
<xi:include href="Common_Content/Legal_Notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
20
server_installation/metadata.ini
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[source]
|
||||||
|
language = en-US
|
||||||
|
type = book
|
||||||
|
markup = asciidoc
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
title = Server Installation and Configuration Guide
|
||||||
|
product = Red Hat Single Sign-On
|
||||||
|
version = 7.0
|
||||||
|
edition =
|
||||||
|
subtitle =
|
||||||
|
keywords =
|
||||||
|
abstract =
|
||||||
|
|
||||||
|
[bugs]
|
||||||
|
reporting_url =
|
||||||
|
type =
|
||||||
|
product =
|
||||||
|
component = Documentation
|
||||||
|
|
BIN
server_installation/rhsso-images/db-module.png
Executable file
After Width: | Height: | Size: 78 KiB |
BIN
server_installation/rhsso-images/domain-boot-files.png
Executable file
After Width: | Height: | Size: 59 KiB |
BIN
server_installation/rhsso-images/domain-file.png
Executable file
After Width: | Height: | Size: 66 KiB |
BIN
server_installation/rhsso-images/domain-json-config.png
Executable file
After Width: | Height: | Size: 7.1 KiB |
BIN
server_installation/rhsso-images/domain-server-dir.png
Executable file
After Width: | Height: | Size: 60 KiB |
BIN
server_installation/rhsso-images/files.png
Executable file
After Width: | Height: | Size: 40 KiB |
BIN
server_installation/rhsso-images/host-files.png
Executable file
After Width: | Height: | Size: 66 KiB |
BIN
server_installation/rhsso-images/standalone-boot-files.png
Executable file
After Width: | Height: | Size: 62 KiB |
BIN
server_installation/rhsso-images/standalone-config-file.png
Executable file
After Width: | Height: | Size: 84 KiB |
BIN
server_installation/rhsso-images/standalone-ha-config-file.png
Executable file
After Width: | Height: | Size: 84 KiB |
BIN
server_installation/rhsso-images/standalone-json-config-file.png
Executable file
After Width: | Height: | Size: 9.2 KiB |
18
server_installation/topics/cache.adoc
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
== Server Cache Configuration
|
||||||
|
|
||||||
|
{{book.project.name}} has two types of caches. One type of cache sits in front of the database to decrease load on the DB
|
||||||
|
and to increase overall response times by keeping data in memory. Realm, client, role, and user metadata is kept in this type of cache.
|
||||||
|
This cache is a local cache. Local caches do not use replication even if you are in the cluster with more {{book.project.name}} servers.
|
||||||
|
Instead, they only keep copies locally and if the entry is updated an invalidation message is sent to the rest of the cluster
|
||||||
|
and the entry is evicted. There is separate replicated cache `work`, which task is to send the invalidation messages to the whole cluster about what entries
|
||||||
|
should be evicted from local caches. This greatly reduces network traffic, makes things efficient, and avoids transmitting sensitive
|
||||||
|
metadata over the wire.
|
||||||
|
|
||||||
|
The second type of cache handles managing user sessions, offline tokens, and keeping track of login failures so that the
|
||||||
|
server can detect password phishing and other attacks. The data held in these caches is temporary, in memory only,
|
||||||
|
but is possibly replicated across the cluster.
|
||||||
|
|
||||||
|
This chapter discusses some configuration options for these caches for both clustered a non-clustered deployments.
|
||||||
|
|
||||||
|
NOTE: More advanced configuration of these caches can be found in the link:{{book.appserver.caching.link}}[Infinispan] section of the _{{book.appserver.caching.name}}_.
|
6
server_installation/topics/cache/clear.adoc
vendored
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
=== Clearing Caches at Runtime
|
||||||
|
|
||||||
|
To clear the realm or user cache, go to the {{book.project.name}} admin console Realm Settings->Cache Config page.
|
||||||
|
On this page you can clear the realm cache, the user cache or cache of external public keys.
|
||||||
|
This will clear the caches for all realms and not only the selected realm.
|
26
server_installation/topics/cache/disable.adoc
vendored
Executable file
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
=== Disabling Caching
|
||||||
|
|
||||||
|
To disable the realm or user cache, you must edit the `standalone.xml`, `standalone-ha.xml`,
|
||||||
|
or `domain.xml` file in your distribution. The location of this file
|
||||||
|
depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>.
|
||||||
|
Here's what the config looks like initially.
|
||||||
|
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
|
||||||
|
<spi name="userCache">
|
||||||
|
<provider name="default" enabled="true"/>
|
||||||
|
</spi>
|
||||||
|
|
||||||
|
<spi name="realmCache">
|
||||||
|
<provider name="default" enabled="true"/>
|
||||||
|
</spi>
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
To disable the cache set the `enabled` attribute to false for the cache you want to disable. You must reboot your
|
||||||
|
server for this change to take effect.
|
||||||
|
|
||||||
|
|
65
server_installation/topics/cache/eviction.adoc
vendored
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
=== Eviction and Expiration
|
||||||
|
|
||||||
|
There are multiple different caches configured for {{book.project.name}}.
|
||||||
|
There is a realm cache that holds information about secured applications, general security data, and configuration options.
|
||||||
|
There is also a user cache that contains user metadata. Both caches default to a maximum of 10000 entries and use a least recently used eviction strategy.
|
||||||
|
Each of them is also tied to an object revisions cache that controls eviction in a clustered setup.
|
||||||
|
This cache is created implicitely and has twice the configured size.
|
||||||
|
There are also separate caches for user sessions, offline tokens, and login failures. These caches are unbounded in size as well.
|
||||||
|
|
||||||
|
The eviction policy and max entries for these caches can be configured in the _standalone.xml_, _standalone-ha.xml_, or
|
||||||
|
_domain.xml_ depending on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>.
|
||||||
|
|
||||||
|
.non-clustered
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:infinispan:4.0">
|
||||||
|
<cache-container name="keycloak" jndi-name="infinispan/Keycloak">
|
||||||
|
<local-cache name="realms">
|
||||||
|
<eviction max-entries="10000" strategy="LRU"/>
|
||||||
|
</local-cache>
|
||||||
|
<local-cache name="users">
|
||||||
|
<eviction max-entries="10000" strategy="LRU"/>
|
||||||
|
</local-cache>
|
||||||
|
<local-cache name="sessions"/>
|
||||||
|
<local-cache name="offlineSessions"/>
|
||||||
|
<local-cache name="loginFailures"/>
|
||||||
|
<local-cache name="work"/>
|
||||||
|
<local-cache name="authorization">
|
||||||
|
<eviction strategy="LRU" max-entries="100"/>
|
||||||
|
</local-cache>
|
||||||
|
<local-cache name="keys">
|
||||||
|
<eviction strategy="LRU" max-entries="1000"/>
|
||||||
|
<expiration max-idle="3600000"/>
|
||||||
|
</local-cache>
|
||||||
|
</cache-container>
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
.clustered
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:infinispan:4.0">
|
||||||
|
<cache-container name="keycloak" jndi-name="infinispan/Keycloak">
|
||||||
|
<transport lock-timeout="60000"/>
|
||||||
|
<local-cache name="realms">
|
||||||
|
<eviction max-entries="10000" strategy="LRU"/>
|
||||||
|
</local-cache>
|
||||||
|
<local-cache name="users">
|
||||||
|
<eviction max-entries="10000" strategy="LRU"/>
|
||||||
|
</local-cache>
|
||||||
|
<distributed-cache name="sessions" mode="SYNC" owners="1"/>
|
||||||
|
<distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
|
||||||
|
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
|
||||||
|
<distributed-cache name="authorization" mode="SYNC" owners="1"/>
|
||||||
|
<replicated-cache name="work" mode="SYNC"/>
|
||||||
|
<local-cache name="keys">
|
||||||
|
<eviction max-entries="1000" strategy="LRU"/>
|
||||||
|
<expiration max-idle="3600000"/>
|
||||||
|
</local-cache>
|
||||||
|
</cache-container>
|
||||||
|
----
|
||||||
|
|
||||||
|
To limit or expand the number of allowed entries simply add or edit the `eviction` element or the `expiration` element of particular cache
|
||||||
|
configuration.
|
25
server_installation/topics/cache/replication.adoc
vendored
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
=== Replication and Failover
|
||||||
|
|
||||||
|
The `sessions`, `offlineSessions` and `loginFailures` caches are the only caches that may perform replication. Entries are
|
||||||
|
not replicated to every single node, but instead one or more nodes is chosen as an owner of that data. If a node is not the owner of a specific cache entry it queries
|
||||||
|
the cluster to obtain it. What this means for failover is that if all the nodes that own a piece of data go down, that data
|
||||||
|
is lost forever. By default, {{book.project.name}} only specifies one owner for data. So if that one node goes down
|
||||||
|
that data is lost. This usually means that users will be logged out and will have to login again.
|
||||||
|
|
||||||
|
You can change the number of nodes that replicate a piece of data by change the `owners` attribute in the `distributed-cache` declaration.
|
||||||
|
|
||||||
|
.owners
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:infinispan:4.0">
|
||||||
|
<cache-container name="keycloak" jndi-name="infinispan/Keycloak">
|
||||||
|
<distributed-cache name="sessions" mode="SYNC" owners="2"/>
|
||||||
|
...
|
||||||
|
----
|
||||||
|
|
||||||
|
Here we've changed it so at least two nodes will replicate one specific user login session.
|
||||||
|
|
||||||
|
TIP: The number of owners recommended is really dependent on your deployment. If you do not care if users are logged
|
||||||
|
out when a node goes down, then one owner is good enough and you will avoid replication.
|
||||||
|
|
17
server_installation/topics/clustering.adoc
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
[[_clustering]]
|
||||||
|
== Clustering
|
||||||
|
|
||||||
|
This section covers configuring {{book.project.name}} to run in a cluster. There's a number
|
||||||
|
of things you have to do when setting up a cluster, specifically:
|
||||||
|
|
||||||
|
* <<fake/../operating-mode.adoc#_operating-mode,Pick an operation mode>>
|
||||||
|
* <<fake/../database.adoc#_database,Configure a shared external database>>
|
||||||
|
* Set up a load balancer
|
||||||
|
* Supplying a private network that supports IP multicast
|
||||||
|
|
||||||
|
Picking an operation mode and configuring a shared database have been discussed earlier in this guide. In this chapter
|
||||||
|
we'll discuss setting up a load balancer and supplying a private network. We'll also discuss some issues that you need
|
||||||
|
to be aware of when booting up a host in the cluster.
|
||||||
|
|
||||||
|
NOTE: It is possible to cluster {{book.project.name}} without IP Multicast, but this topic is beyond the scope of this guide. For more information, see link:{{book.appserver.jgroups.link}}[JGroups] chapter of the _{{book.appserver.jgroups.name}}_.
|
18
server_installation/topics/clustering/booting.adoc
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
=== Booting the Cluster
|
||||||
|
|
||||||
|
Booting {{book.project.name}} in a cluster depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>
|
||||||
|
|
||||||
|
.Standalone Mode
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ bin/standalone.sh --server-config=standalone-ha.xml
|
||||||
|
----
|
||||||
|
|
||||||
|
.Domain Mode
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ bin/domain.sh --host-config=host-master.xml
|
||||||
|
$ bin/domain.sh --host-config=host-slave.xml
|
||||||
|
----
|
||||||
|
|
6
server_installation/topics/clustering/example.adoc
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
=== Clustering Example
|
||||||
|
|
||||||
|
{{book.project.name}} does come with an out of the box clustering demo that leverages domain mode. Review the
|
||||||
|
<<fake/../../operating-mode/domain.adoc#_clustered-domain-example, Clustered Domain Example>> chapter for more details.
|
||||||
|
|
225
server_installation/topics/clustering/load-balancer.adoc
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
|
||||||
|
=== Setting Up a Load Balancer or Proxy
|
||||||
|
|
||||||
|
This section discusses a number of things you need to configure before you can put a reverse proxy or load balancer
|
||||||
|
in front of your clustered {{book.project.name}} deployment. It also covers configuring the built in load balancer that
|
||||||
|
was <<fake/../../operating-mode/domain.adoc#_clustered-domain-example, Clustered Domain Example>>.
|
||||||
|
|
||||||
|
|
||||||
|
==== Identifying Client IP Addresses
|
||||||
|
|
||||||
|
A few features in {{book.project.name}} rely on the fact that the remote
|
||||||
|
address of the HTTP client connecting to the authentication server is the real IP address of the client machine. Examples include:
|
||||||
|
|
||||||
|
* Event logs - a failed login attempt would be logged with the wrong source IP address
|
||||||
|
* SSL required - if the SSL required is set to external (the default) it should require SSL for all external requests
|
||||||
|
* Authentication flows - a custom authentication flow that uses the IP address to for example show OTP only for external requests
|
||||||
|
* Dynamic Client Registration
|
||||||
|
|
||||||
|
This can be problematic when you have a reverse proxy or loadbalancer in front of your {{book.project.name}} authentication server.
|
||||||
|
The usual setup is that you have a frontend proxy sitting on a public network that load balances and forwards requests
|
||||||
|
to backend {{book.project.name}} server instances located in a private network. There is some extra configuration you have to do in this scenario
|
||||||
|
so that the actual client IP address is forwarded to and processed by the {{book.project.name}} server instances. Specifically:
|
||||||
|
|
||||||
|
* Configure your reverse proxy or loadbalancer to properly set `X-Forwarded-For` and `X-Forwarded-Proto` HTTP headers.
|
||||||
|
* Configure your reverse proxy or loadbalancer to preserve the original 'Host' HTTP header.
|
||||||
|
* Configure the authentication server to read the client's IP address from `X-Forwarded-For header`.
|
||||||
|
|
||||||
|
Configuring your proxy to generate the `X-Forwarded-For` and `X-Forwarded-Proto` HTTP headers and preserving the
|
||||||
|
original `Host` HTTP header is beyond the scope of this guide. Take extra precautions to ensure that the
|
||||||
|
`X-Forwared-For` header is set by your proxy. If your proxy isn't configured correctly, then _rogue_ clients can set this header themselves and trick {{book.project.name}}
|
||||||
|
into thinking the client is connecting from a different IP address than it actually is. This becomes really important if you are doing
|
||||||
|
any black or white listing of IP addresses.
|
||||||
|
|
||||||
|
Beyond the proxy itself, there are a few things you need to configure on the {{book.project.name}} side of things.
|
||||||
|
If your proxy is forwarding requests via the HTTP protocol, then you need to configure {{book.project.name}} to pull the client's
|
||||||
|
IP address from the `X-Forwarded-For` header rather than from the network packet.
|
||||||
|
To do this, open up the profile configuration file (_standalone.xml_, _standalone-ha.xml_, or _domain.xml_ depending on your
|
||||||
|
<<fake/../../operating-mode.adoc#_operating-mode, operating mode>>) and look for the `"urn:jboss:domain:undertow:3.0` XML block.
|
||||||
|
|
||||||
|
.`X-Forwarded-For` HTTP Config
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:undertow:3.0">
|
||||||
|
<buffer-cache name="default"/>
|
||||||
|
<server name="default-server">
|
||||||
|
<ajp-listener name="ajp" socket-binding="ajp"/>
|
||||||
|
<http-listener name="default" socket-binding="http" redirect-socket="https"
|
||||||
|
proxy-address-forwarding="true"/>
|
||||||
|
...
|
||||||
|
</server>
|
||||||
|
...
|
||||||
|
</subsystem>
|
||||||
|
----
|
||||||
|
|
||||||
|
Add the `proxy-address-forwarding` attribute to the `http-listener` element. Set the value to `true`.
|
||||||
|
|
||||||
|
If your proxy is using the AJP protocol instead of HTTP to forward requests (i.e. Apache HTTPD + mod-cluster), then you have
|
||||||
|
to configure things a little differently. Instead of modifying the `http-listener`, you need to add a filter to
|
||||||
|
pull this information from the AJP packets.
|
||||||
|
|
||||||
|
|
||||||
|
.`X-Forwarded-For` AJP Config
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:undertow:3.0">
|
||||||
|
<buffer-cache name="default"/>
|
||||||
|
<server name="default-server">
|
||||||
|
<ajp-listener name="ajp" socket-binding="ajp"/>
|
||||||
|
<http-listener name="default" socket-binding="http" redirect-socket="https"/>
|
||||||
|
<host name="default-host" alias="localhost">
|
||||||
|
...
|
||||||
|
<filter-ref name="proxy-peer"/>
|
||||||
|
</host>
|
||||||
|
</server>
|
||||||
|
...
|
||||||
|
<filters>
|
||||||
|
...
|
||||||
|
<filter name="proxy-peer"
|
||||||
|
class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"
|
||||||
|
module="io.undertow.core" />
|
||||||
|
</filters>
|
||||||
|
</subsystem>
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Enable HTTPS/SSL with a Reverse Proxy
|
||||||
|
|
||||||
|
Assuming that your reverse proxy doesn't use port 8443 for SSL you also need to configure what port HTTPS traffic is redirected to.
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:undertow:3.0">
|
||||||
|
...
|
||||||
|
<http-listener name="default" socket-binding="http"
|
||||||
|
proxy-address-forwarding="true" redirect-socket="proxy-https"/>
|
||||||
|
...
|
||||||
|
</subsystem>
|
||||||
|
----
|
||||||
|
|
||||||
|
Add the `redirect-socket` attribute to the `http-listener` element. The value should be `proxy-https` which points to a
|
||||||
|
socket binding you also need to define.
|
||||||
|
|
||||||
|
Then add a new `socket-binding` element to the `socket-binding-group` element:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
|
||||||
|
<socket-binding-group name="standard-sockets" default-interface="public"
|
||||||
|
port-offset="${jboss.socket.binding.port-offset:0}">
|
||||||
|
...
|
||||||
|
<socket-binding name="proxy-https" port="443"/>
|
||||||
|
...
|
||||||
|
</socket-binding-group>
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Verify Configuration
|
||||||
|
|
||||||
|
You can verify the reverse proxy or load balancer configuration by opening the path `/auth/realms/master/.well-known/openid-configuration`
|
||||||
|
through the reverse proxy. For example if the reverse proxy address is `https://acme.com/` then open the URL
|
||||||
|
`https://acme.com/auth/realms/master/.well-known/openid-configuration`. This will show a JSON document listing a number
|
||||||
|
of endpoints for {{book.project.name}}. Make sure the endpoints starts with the address (scheme, domain and port) of your
|
||||||
|
reverse proxy or load balancer. By doing this you make sure that {{book.project.name}} is using the correct endpoint.
|
||||||
|
|
||||||
|
You should also verify that {{book.project.name}} sees the correct source IP address for requests. Do check this you can
|
||||||
|
try to login to the admin console with an invalid username and/or password. This should show a warning in the server log
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
08:14:21,287 WARN XNIO-1 task-45 [org.keycloak.events] type=LOGIN_ERROR, realmId=master, clientId=security-admin-console, userId=8f20d7ba-4974-4811-a695-242c8fbd1bf8, ipAddress=X.X.X.X, error=invalid_user_credentials, auth_method=openid-connect, auth_type=code, redirect_uri=http://localhost:8080/auth/admin/master/console/?redirect_fragment=%2Frealms%2Fmaster%2Fevents-settings, code_id=a3d48b67-a439-4546-b992-e93311d6493e, username=admin
|
||||||
|
----
|
||||||
|
|
||||||
|
Check that the value of `ipAddress` is the IP address of the machine you tried to login with and not the IP address
|
||||||
|
of the reverse proxy or load balancer.
|
||||||
|
|
||||||
|
==== Using the Built-In Load Balancer
|
||||||
|
|
||||||
|
This section covers configuring the built in load balancer that is discussed in the
|
||||||
|
<<fake/../../operating-mode/domain.adoc#_clustered-domain-example, Clustered Domain Example>>.
|
||||||
|
|
||||||
|
The <<fake/../../operating-mode/domain.adoc#_clustered-domain-example, Clustered Domain Example>> is only designed to run
|
||||||
|
on one machine. To bring up a slave on another host, you'll need to
|
||||||
|
|
||||||
|
. Edit the _domain.xml_ file to point to your new host slave
|
||||||
|
. Copy the server distribution. You don't need the _domain.xml_, _host.xml_, or _host-master.xml_ files. Nor do you need
|
||||||
|
the _standalone/_ directory.
|
||||||
|
. Edit the _host-slave.xml_ file to change the bind addresses used or override them on the command line
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
===== Register a New Host With Load Balancer
|
||||||
|
|
||||||
|
Let's look first at registering the new host slave with the load balancer configuration in _domain.xml_. Open this
|
||||||
|
file and go to the undertow configuration in the `load-balancer` profile. Add a new `host` definition called
|
||||||
|
`remote-host3` within the `reverse-proxy` XML block.
|
||||||
|
|
||||||
|
.domain.xml reverse-proxy config
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:undertow:3.0">
|
||||||
|
...
|
||||||
|
<handlers>
|
||||||
|
<reverse-proxy name="lb-handler">
|
||||||
|
<host name="host1" outbound-socket-binding="remote-host1" scheme="ajp" path="/" instance-id="myroute1"/>
|
||||||
|
<host name="host2" outbound-socket-binding="remote-host2" scheme="ajp" path="/" instance-id="myroute2"/>
|
||||||
|
<host name="remote-host3" outbound-socket-binding="remote-host3" scheme="ajp" path="/" instance-id="myroute3"/>
|
||||||
|
</reverse-proxy>
|
||||||
|
</handlers>
|
||||||
|
...
|
||||||
|
</subsystem>
|
||||||
|
----
|
||||||
|
|
||||||
|
The `output-socket-binding` is a logical name pointing to a `socket-binding` configured later in the _domain.xml_ file.
|
||||||
|
the `instance-id` attribute must also be unique to the new host as this value is used by a cookie to enable sticky
|
||||||
|
sessions when load balancing.
|
||||||
|
|
||||||
|
Next go down to the `load-balancer-sockets` `socket-binding-group` and add the `outbound-socket-binding` for `remote-host3`. This new
|
||||||
|
binding needs to point to the host and port of the new host.
|
||||||
|
|
||||||
|
.domain.xml outbound-socket-binding
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<socket-binding-group name="load-balancer-sockets" default-interface="public">
|
||||||
|
...
|
||||||
|
<outbound-socket-binding name="remote-host1">
|
||||||
|
<remote-destination host="localhost" port="8159"/>
|
||||||
|
</outbound-socket-binding>
|
||||||
|
<outbound-socket-binding name="remote-host2">
|
||||||
|
<remote-destination host="localhost" port="8259"/>
|
||||||
|
</outbound-socket-binding>
|
||||||
|
<outbound-socket-binding name="remote-host3">
|
||||||
|
<remote-destination host="192.168.0.5" port="8259"/>
|
||||||
|
</outbound-socket-binding>
|
||||||
|
</socket-binding-group>
|
||||||
|
----
|
||||||
|
|
||||||
|
===== Master Bind Addresses
|
||||||
|
|
||||||
|
Next thing you'll have to do is to change the `public` and `management` bind addresses for the master host. Either
|
||||||
|
edit the _domain.xml_ file as discussed in the <<fake/../../network/bind-address.adoc#_bind-address, Bind Addresses>> chapter
|
||||||
|
or specify these bind addresses on the command line as follows:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ domain.sh --host-config=host-master.xml -Djboss.bind.address=192.168.0.2 -Djboss.bind.address.management=192.168.0.2
|
||||||
|
----
|
||||||
|
|
||||||
|
===== Host Slave Bind Addresses
|
||||||
|
|
||||||
|
Next you'll have to change the `public`, `management`, and domain controller bind addresses (`jboss.domain.master-address`). Either edit the
|
||||||
|
_host-slave.xml_ file or specify them on the command line as follows:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ domain.sh --host-config=host-slave.xml
|
||||||
|
-Djboss.bind.address=192.168.0.5
|
||||||
|
-Djboss.bind.address.management=192.168.0.5
|
||||||
|
-Djboss.domain.master.address=192.168.0.2
|
||||||
|
----
|
||||||
|
|
||||||
|
The values of `jboss.bind.address` and `jboss.bind.addres.management` pertain to the host slave's IP address.
|
||||||
|
The value of `jboss.domain.master.address` need to be the IP address of the domain controller which is the management address
|
||||||
|
of the master host.
|
||||||
|
|
||||||
|
==== Configuring Other Load Balancers
|
||||||
|
|
||||||
|
See link:{{book.appserver.loadbalancer.link}}[the load balancing] section in the _{{book.appserver.loadbalancer.name}}_ for information how to use other software-based load balancers.
|
34
server_installation/topics/clustering/multicast.adoc
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
=== Multicast Network Setup
|
||||||
|
|
||||||
|
Out of the box clustering support has a need to for IP Multicast. Multicast is a network broadcast protocol. This protocol
|
||||||
|
is used at boot time to discover and join the cluster. It is also used to broadcast messages for the replication and invalidation
|
||||||
|
distributed caches used by {{book.project.name}}.
|
||||||
|
|
||||||
|
The clustering subsystem for {{book.project.name}} runs on the JGroups stack. Out of the box, the bind addresses for clustering are bound to a private network interface with a default IP address of 127.0.0.1.
|
||||||
|
You'll have to edit your the _standalone-ha.xml_ or _domain.xml_ sections discussed in the <<fake/../../network/bind-address.adoc#_bind-address,Bind Address>> chapter.
|
||||||
|
|
||||||
|
.private network config
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<interfaces>
|
||||||
|
...
|
||||||
|
<interface name="private">
|
||||||
|
<inet-address value="${jboss.bind.address.private:127.0.0.1}"/>
|
||||||
|
</interface>
|
||||||
|
</interfaces>
|
||||||
|
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||||
|
...
|
||||||
|
<socket-binding name="jgroups-mping" interface="private" port="0" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45700"/>
|
||||||
|
<socket-binding name="jgroups-tcp" interface="private" port="7600"/>
|
||||||
|
<socket-binding name="jgroups-tcp-fd" interface="private" port="57600"/>
|
||||||
|
<socket-binding name="jgroups-udp" interface="private" port="55200" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45688"/>
|
||||||
|
<socket-binding name="jgroups-udp-fd" interface="private" port="54200"/>
|
||||||
|
<socket-binding name="modcluster" port="0" multicast-address="224.0.1.105" multicast-port="23364"/>
|
||||||
|
...
|
||||||
|
</socket-binding-group>
|
||||||
|
----
|
||||||
|
|
||||||
|
Things you'll want to configure are the `jboss.bind.address.private` and `jboss.default.multicast.address` as well as the ports of the services on the clustering stack.
|
||||||
|
|
||||||
|
NOTE: It is possible to cluster {{book.project.name}} without IP Multicast, but this topic is beyond the scope of this guide. For more information, see link:{{book.appserver.jgroups.link}}[JGroups] in the _{{book.appserver.jgroups.name}}_.
|
10
server_installation/topics/clustering/recommended.adoc
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
=== Recommended Network Architecture
|
||||||
|
|
||||||
|
The recommended network architecture for deploying {{book.project.name}} is to set up an HTTP/HTTPS load balancer on
|
||||||
|
a public IP address that routes requests to {{book.project.name}} servers sitting on a private network. This
|
||||||
|
isolates all clustering connections and provides a nice means of protecting the servers.
|
||||||
|
|
||||||
|
NOTE: By default, there is nothing to prevent unauthorized nodes from joining the cluster and broadcasting multicast messages.
|
||||||
|
This is why cluster nodes should be in a private network, with a firewall protecting them from outside attacks.
|
||||||
|
|
29
server_installation/topics/clustering/serialized.adoc
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
[[_clustering_db_lock]]
|
||||||
|
=== Serialized Cluster Startup
|
||||||
|
|
||||||
|
{{book.project.name}} cluster nodes are allowed to boot concurrenty.
|
||||||
|
When {{book.project.name}} server instance boots up it may do some database migration, importing, or first time initializations.
|
||||||
|
A DB lock is used to prevent start actions from conflicting with one another when cluster nodes boot up concurrently.
|
||||||
|
|
||||||
|
By default, the maximum timeout for this lock is 900 seconds. If a node is waiting on this lock for more than the timeout
|
||||||
|
it will fail to boot.
|
||||||
|
Typically you won't need to increase/decrease the default value, but just in case it's possible to configure it in
|
||||||
|
`standalone.xml`, `standalone-ha.xml`, or `domain.xml` file in your distribution. The location of this file
|
||||||
|
depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="dblock">
|
||||||
|
<provider name="jpa" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="lockWaitTimeout" value="900"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
----
|
||||||
|
|
||||||
|
{% if book.community %}
|
||||||
|
If you are using Mongo DB replace `jpa` with `mongo`.
|
||||||
|
{% endif %}
|
||||||
|
|
19
server_installation/topics/clustering/troubleshooting.adoc
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
=== Troubleshooting
|
||||||
|
|
||||||
|
Note that when you run cluster, you should see message similar to this in the log of both cluster nodes:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (Incoming-10,shared=udp)
|
||||||
|
ISPN000094: Received new cluster view: [node1/keycloak|1] (2) [node1/keycloak, node2/keycloak]
|
||||||
|
----
|
||||||
|
If you see just one node mentioned, it's possible that your cluster hosts are not joined together.
|
||||||
|
|
||||||
|
Usually it's best practice to have your cluster nodes on private network without firewall for communication among them.
|
||||||
|
Firewall could be enabled just on public access point to your network instead.
|
||||||
|
If for some reason you still need to have firewall enabled on cluster nodes, you will need to open some ports.
|
||||||
|
Default values are UDP port 55200 and multicast port 45688 with multicast address 230.0.0.4.
|
||||||
|
Note that you may need more ports opened if you want to enable additional features like diagnostics for your JGroups stack.
|
||||||
|
{{book.project.name}} delegates most of the clustering work to Infinispan/JGroups.
|
||||||
|
For more information, see link:{{book.appserver.jgroups.link}}[JGroups] in the _{{book.appserver.jgroups.name}}_.
|
23
server_installation/topics/config-subsystem.adoc
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
[[_manage_config]]
|
||||||
|
|
||||||
|
== Manage Subsystem Configuration
|
||||||
|
|
||||||
|
Low-level configuration of {{book.project.name}} is done by editing the
|
||||||
|
`standalone.xml`, `standalone-ha.xml`, or `domain.xml` file
|
||||||
|
in your distribution. The location of this file
|
||||||
|
depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>.
|
||||||
|
|
||||||
|
While there are endless settings you can configure here, this section will focus on
|
||||||
|
configuration of the _keycloak-server_ subsystem. No matter which configuration file
|
||||||
|
you are using, configuration of the _keycloak-server_ subsystem is the same.
|
||||||
|
|
||||||
|
The keycloak-server subsystem is typically declared toward the end of the file like this:
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
||||||
|
<web-context>auth</web-context>
|
||||||
|
...
|
||||||
|
</subsystem>
|
||||||
|
----
|
||||||
|
|
||||||
|
Note that anything changed in this subsystem will not take effect until the server is rebooted.
|
63
server_installation/topics/config-subsystem/cli-recipes.adoc
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
[[_cli_recipes]]
|
||||||
|
|
||||||
|
=== CLI Recipes
|
||||||
|
Here are some configuration tasks and how to perform them with CLI commands.
|
||||||
|
Note that in all but the first example, we use the wildcard path `**` to mean
|
||||||
|
you should substitute or the path to the keycloak-server subsystem.
|
||||||
|
|
||||||
|
For standalone, this just means:
|
||||||
|
|
||||||
|
`**` = `/subsystem=keycloak-server`
|
||||||
|
|
||||||
|
For domain mode, this would mean something like:
|
||||||
|
|
||||||
|
`**` = `/profile=auth-server-clustered/subsystem=keycloak-server`
|
||||||
|
|
||||||
|
==== Change the web context of the server
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
/subsystem=keycloak-server/:write-attribute(name=web-context,value=myContext)
|
||||||
|
----
|
||||||
|
==== Set the global default theme
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
**/theme=defaults/:write-attribute(name=default,value=myTheme)
|
||||||
|
----
|
||||||
|
==== Add a new SPI and a provider
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
**/spi=mySPI/:add
|
||||||
|
**/spi=mySPI/provider=myProvider/:add(enabled=true)
|
||||||
|
----
|
||||||
|
==== Disable a provider
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
**/spi=mySPI/provider=myProvider/:write-attribute(name=enabled,value=false)
|
||||||
|
----
|
||||||
|
==== Change the default provider for an SPI
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
**/spi=mySPI/:write-attribute(name=default-provider,value=myProvider)
|
||||||
|
----
|
||||||
|
==== Configure the dblock SPI with both jpa and mango providers
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
**/spi=dblock/:add(default-provider=jpa)
|
||||||
|
**/spi=dblock/provider=jpa/:add(properties={lockWaitTimeout => "900"},enabled=true)
|
||||||
|
**/spi=dblock/provider=mongo/:add(properties={lockRecheckTime => "2",lockWaitTimeout => "800"},enabled=true)
|
||||||
|
----
|
||||||
|
==== Add or change a single property value for a provider
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
**/spi=dblock/provider=mongo/:map-put(name=properties,key=lockRecheckTime,value=3)
|
||||||
|
----
|
||||||
|
==== Remove a single property from a provider
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
**/spi=dblock/provider=mongo/:map-remove(name=properties,key=lockRecheckTime)
|
||||||
|
----
|
||||||
|
==== Set values on a provider property of type `List`
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
**/spi=eventsStore/provider=jpa/:map-put(name=properties,key=exclude-events,value=[EVENT1,EVENT2])
|
||||||
|
----
|
|
@ -0,0 +1,59 @@
|
||||||
|
[[_config_spi_providers]]
|
||||||
|
|
||||||
|
=== Configure SPI Providers
|
||||||
|
|
||||||
|
The specifics of each configuration setting is discussed elsewhere in
|
||||||
|
context with that setting. However, it is useful to understand the format used
|
||||||
|
to declare settings on SPI providers.
|
||||||
|
|
||||||
|
{{book.project.name}} is a highly modular system that allows great
|
||||||
|
flexibility. There are more than 50 service provider interfaces (SPIs), and
|
||||||
|
you are allowed to swap out implementations of each SPI. An implementation of
|
||||||
|
an SPI is known as a _provider_.
|
||||||
|
|
||||||
|
All elements in an SPI declaration are optional, but a full SPI declaration
|
||||||
|
looks like this:
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="dblock">
|
||||||
|
<default-provider>mongo</default-provider>
|
||||||
|
<provider name="jpa" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="lockWaitTimeout" value="800"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
<provider name="mongo" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="lockRecheckTime" value="2"/>
|
||||||
|
<property name="lockWaitTimeout" value="600"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
----
|
||||||
|
Here we have two providers defined for the SPI `dblock`. The `default-provider`
|
||||||
|
is listed as `mongo`. However it is up to the SPI to decide how it will treat
|
||||||
|
this setting. Some SPIs allow more than one provider and some do not. So
|
||||||
|
`default-provider` can help the SPI to choose.
|
||||||
|
|
||||||
|
Also notice that each provider defines its own set of configuration properties.
|
||||||
|
The fact that both providers above have a property called `lockWaitTimeout` is just a
|
||||||
|
coincidence.
|
||||||
|
|
||||||
|
The type of each property value is interpreted by the provider. However, there
|
||||||
|
is one exception. Consider the `jpa` provider for the `eventStore` API:
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="eventsStore">
|
||||||
|
<provider name="jpa" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="exclude-events" value="["EVENT1",
|
||||||
|
"EVENT2"]"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
----
|
||||||
|
We see that the value begins and ends with square brackets. That means that
|
||||||
|
the value will be passed to the provider as a list. In this example, the system will pass the
|
||||||
|
provider a list with two element values _EVENT1_ and _EVENT2_. To add more values
|
||||||
|
to the list, just separate each list element with a comma. Unfortunately,
|
||||||
|
you do need to escape the quotes surrounding each list element with `\"`.
|
101
server_installation/topics/config-subsystem/start-cli.adoc
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
[[_start_cli]]
|
||||||
|
|
||||||
|
=== Start the {{book.appserver.name}} CLI
|
||||||
|
Besides editing the configuration by hand, you also have the option of changing
|
||||||
|
the configuration by issuing commands via the _jboss-cli_ tool. CLI allows
|
||||||
|
you to configure servers locally or remotely. And it is especially useful when
|
||||||
|
combined with scripting.
|
||||||
|
|
||||||
|
To start the {{book.appserver.name}} CLI, you need to run `jboss-cli`.
|
||||||
|
|
||||||
|
.Linux/Unix
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ .../bin/jboss-cli.sh
|
||||||
|
----
|
||||||
|
|
||||||
|
.Windows
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
> ...\bin\jboss-cli.bat
|
||||||
|
----
|
||||||
|
|
||||||
|
This will bring you to a prompt like this:
|
||||||
|
|
||||||
|
.Prompt
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
[disconnected /]
|
||||||
|
----
|
||||||
|
|
||||||
|
If you wish to execute commands on a running server, you will first
|
||||||
|
execute the `connect` command.
|
||||||
|
|
||||||
|
.connect
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
[disconnected /] connect
|
||||||
|
connect
|
||||||
|
[standalone@localhost:9990 /]
|
||||||
|
----
|
||||||
|
|
||||||
|
You may be thinking to yourself, "I didn't enter in any username or password!". If you run `jboss-cli` on the same machine
|
||||||
|
as your running standalone server or domain controller and your account has appropriate file permissions, you do not have
|
||||||
|
to setup or enter in a admin username and password. See the link:{{book.appserver.admindoc.link}}[_{{book.appserver.admindoc.name}}_]
|
||||||
|
for more details on how to make things more secure if you are uncomfortable with that setup.
|
||||||
|
|
||||||
|
=== CLI Embedded Mode
|
||||||
|
|
||||||
|
If you do happen to be on the same machine as your standalone server and you want to
|
||||||
|
issue commands while the server is not active, you can embed the server into CLI and make
|
||||||
|
changes in a special mode that disallows incoming requests. To do this, first
|
||||||
|
execute the `embed` command with the config file you wish to change.
|
||||||
|
|
||||||
|
.embed
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
[disconnected /] embed-server --server-config=standalone.xml
|
||||||
|
[standalone@embedded /]
|
||||||
|
----
|
||||||
|
|
||||||
|
=== CLI GUI Mode
|
||||||
|
|
||||||
|
The CLI can also run in GUI mode. GUI mode launches a Swing application that
|
||||||
|
allows you to graphically view and edit the entire management model of a _running_ server.
|
||||||
|
GUI mode is especially useful when you need help formatting your CLI commands and learning
|
||||||
|
about the options available. The GUI can also retrieve server logs from a local or
|
||||||
|
remote server.
|
||||||
|
|
||||||
|
.Start in GUI mode
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ .../bin/jboss-cli.sh --gui
|
||||||
|
----
|
||||||
|
_Note: to connect to a remote server, you pass the `--connect` option as well.
|
||||||
|
Use the --help option for more details._
|
||||||
|
|
||||||
|
After launching GUI mode, you will probably want to scroll down to find the node,
|
||||||
|
`subsystem=keycloak-server`. If you right-click on the node and click
|
||||||
|
`Explore subsystem=keycloak-server`, you will get a new tab that shows only
|
||||||
|
the keycloak-server subsystem.
|
||||||
|
|
||||||
|
image:../../images/cli-gui.png[]
|
||||||
|
|
||||||
|
=== CLI Scripting
|
||||||
|
|
||||||
|
The CLI has extensive scripting capabilities. A script is just a text
|
||||||
|
file with CLI commands in it. Consider a simple script that turns off theme
|
||||||
|
and template caching.
|
||||||
|
|
||||||
|
.turn-off-caching.cli
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes,value=false)
|
||||||
|
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates,value=false)
|
||||||
|
----
|
||||||
|
To execute the script, I can follow the `Scripts` menu in CLI GUI, or execute the
|
||||||
|
script from the command line as follows:
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ .../bin/jboss-cli.sh --file=turn-off-caching.cli
|
||||||
|
----
|
19
server_installation/topics/database.adoc
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
[[_database]]
|
||||||
|
|
||||||
|
== Relational Database Setup
|
||||||
|
{{book.project.name}} comes with its own embedded Java-based relational database called H2.
|
||||||
|
This is the default database that {{book.project.name}} will use to persist data and really only exists so that you can run the authentication
|
||||||
|
server out of the box. We highly recommend that you replace it with a more production ready external database. The H2 database
|
||||||
|
is not very viable in high concurrency situations and should not be used in a cluster either. The purpose of this chapter is to
|
||||||
|
show you how to connect {{book.project.name}} to a more mature database.
|
||||||
|
|
||||||
|
{{book.project.name}} uses two layered technologies to persist its relational data. The bottom layered technology is JDBC. JDBC
|
||||||
|
is a Java API that is used to connect to a RDBMS. There are different JDBC drivers per database type that are provided
|
||||||
|
by your database vendor. This chapter discusses how to configure {{book.project.name}} to use one of these vendor-specific drivers.
|
||||||
|
|
||||||
|
The top layered technology for persistence is Hibernate JPA. This is a object to relational mapping API that maps Java
|
||||||
|
Objects to relational data. Most deployments of {{book.project.name}} will never have to touch the configuration aspects
|
||||||
|
of Hibernate, but we will discuss how that is done if you run into that rare circumstance.
|
||||||
|
|
||||||
|
NOTE: Datasource configuration is covered much more thoroughly in link:{{book.appserver.datasource.link}}[the datasource configuration chapter]
|
||||||
|
in the _{{book.appserver.admindoc.name}}_.
|
13
server_installation/topics/database/checklist.adoc
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
=== RDBMS Setup Checklist
|
||||||
|
|
||||||
|
These are the steps you will need to perform to get an RDBMS configured for {{book.project.name}}.
|
||||||
|
|
||||||
|
. Locate and download a JDBC driver for your database
|
||||||
|
. Package the driver JAR into a module and install this module into the server
|
||||||
|
. Declare the JDBC driver in the configuration profile of the server
|
||||||
|
. Modify the datasource configuration to use your database's JDBC driver
|
||||||
|
. Modify the datasource configuration to define the connection parameters to your database
|
||||||
|
|
||||||
|
This chapter will use PostgresSQL for all its examples. Other databases follow the same steps for installation.
|
||||||
|
|
45
server_installation/topics/database/datasource.adoc
Executable file
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
=== Modify the {{book.project.name}} Datasource
|
||||||
|
|
||||||
|
After declaring your JDBC driver, you have to modify the existing datasource configuration that {{book.project.name}} uses
|
||||||
|
to connect it to your new external database. You'll do
|
||||||
|
this within the same configuration file and XML block that you registered your JDBC driver in. Here's an example
|
||||||
|
that sets up the connection to your new database:
|
||||||
|
|
||||||
|
.Declare Your JDBC Drivers
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
|
||||||
|
<datasources>
|
||||||
|
...
|
||||||
|
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
|
||||||
|
<connection-url>jdbc:postgresql://localhost/keycloak</connection-url>
|
||||||
|
<driver>postgresql</driver>
|
||||||
|
<pool>
|
||||||
|
<max-pool-size>20</max-pool-size>
|
||||||
|
</pool>
|
||||||
|
<security>
|
||||||
|
<user-name>William</user-name>
|
||||||
|
<password>password</password>
|
||||||
|
</security>
|
||||||
|
</datasource>
|
||||||
|
...
|
||||||
|
</datasources>
|
||||||
|
</subsystem>
|
||||||
|
----
|
||||||
|
|
||||||
|
Search for the `datasource` definition for `KeycloakDS`. You'll first need to modify the `connection-url`. The
|
||||||
|
documentation for your vendor's JDBC implementation should specify the format for this connection URL value.
|
||||||
|
|
||||||
|
Next define the `driver` you will use. This is the logical name of the JDBC driver you declared in the previous section of this
|
||||||
|
chapter.
|
||||||
|
|
||||||
|
It is expensive to open a new connection to a database every time you want to perform a transaction. To compensate, the datasource
|
||||||
|
implementation maintains a pool of open connections. The `max-pool-size` specifies the maximum number of connections it will pool.
|
||||||
|
You may want to change the value of this depending on the load of your system.
|
||||||
|
|
||||||
|
Finally, with PostgreSQL at least, you need to define the database username and password that is needed to connect to the database. You
|
||||||
|
may be worried that this is in clear text in the example. There are methods to obfuscate this, but this is beyond the
|
||||||
|
scope of this guide.
|
||||||
|
|
||||||
|
NOTE: For more information about datasource features, see link:{{book.appserver.datasource.link}}[the datasource configuration chapter] in the _{{book.appserver.admindoc.name}}_.
|
57
server_installation/topics/database/hibernate.adoc
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
|
||||||
|
=== Database Configuration
|
||||||
|
|
||||||
|
The configuration for this component lies in the `standalone.xml`, `standalone-ha.xml`, or `domain.xml` file
|
||||||
|
in your distribution. The location of this file
|
||||||
|
depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>.
|
||||||
|
|
||||||
|
.Database Config
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="connectionsJpa">
|
||||||
|
<provider name="default" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
|
||||||
|
<property name="initializeEmpty" value="false"/>
|
||||||
|
<property name="migrationStrategy" value="manual"/>
|
||||||
|
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
----
|
||||||
|
|
||||||
|
Possible configuration options are:
|
||||||
|
|
||||||
|
dataSource::
|
||||||
|
JNDI name of the dataSource
|
||||||
|
|
||||||
|
jta::
|
||||||
|
boolean property to specify if datasource is JTA capable
|
||||||
|
|
||||||
|
driverDialect::
|
||||||
|
Value of database dialect.
|
||||||
|
In most cases you don't need to specify this property as dialect will be autodetected by Hibernate.
|
||||||
|
|
||||||
|
initializeEmpty::
|
||||||
|
Initialize database if empty. If set to false the database has to be manually initialized. If you want to manually initialize the database set migrationStrategy to `manual` which will create a file with SQL commands to initialize the database. Defaults to true.
|
||||||
|
|
||||||
|
migrationStrategy::
|
||||||
|
Strategy to use to migrate database. Valid values are `update`, `manual` and `validate`. Update will automatically migrate the database schema. Manual will export the required changes to a file with SQL commands that you can manually execute on the database. Validate will simply check if the database is up-to-date.
|
||||||
|
|
||||||
|
migrationExport::
|
||||||
|
Path for where to write manual database initialization/migration file.
|
||||||
|
|
||||||
|
showSql::
|
||||||
|
Specify whether Hibernate should show all SQL commands in the console (false by default). This is very verbose!
|
||||||
|
|
||||||
|
formatSql::
|
||||||
|
Specify whether Hibernate should format SQL commands (true by default)
|
||||||
|
|
||||||
|
globalStatsInterval::
|
||||||
|
Will log global statistics from Hibernate about executed DB queries and other things.
|
||||||
|
Statistics are always reported to server log at specified interval (in seconds) and are cleared after each report.
|
||||||
|
|
||||||
|
schema::
|
||||||
|
Specify the database schema to use
|
||||||
|
|
||||||
|
NOTE: These configuration switches and more are described in the link:{{book.appserver.jpa.link}}[_{{book.appserver.jpa.name}}_].
|
91
server_installation/topics/database/jdbc.adoc
Executable file
|
@ -0,0 +1,91 @@
|
||||||
|
|
||||||
|
=== Package the JDBC Driver
|
||||||
|
|
||||||
|
Find and download the JDBC driver JAR for your RDBMS. Before you can use this driver, you must package it up into a module
|
||||||
|
and install it into the server.
|
||||||
|
Modules define JARs that are loaded into the {{book.project.name}} classpath and the dependencies those JARs have on
|
||||||
|
other modules. They are pretty simple to set up.
|
||||||
|
|
||||||
|
Within the _.../modules/_ directory of your
|
||||||
|
{{book.project.name}} distribution, you need to create a directory structure to hold your module definition. The convention is use the Java package name
|
||||||
|
of the JDBC driver for the name of the directory structure. For PostgreSQL, create the directory _org/postgresql/main_. Copy your database
|
||||||
|
driver JAR into this directory and create an empty _module.xml_ file within it too.
|
||||||
|
|
||||||
|
.Module Directory
|
||||||
|
image:../../{{book.images}}/db-module.png[]
|
||||||
|
|
||||||
|
After you have done this, open up the _module.xml_ file and create the following XML
|
||||||
|
|
||||||
|
.Module XML
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<module xmlns="urn:jboss:module:1.3" name="org.postgresql">
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<resource-root path="postgresql-9.4.1208.jar"/>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<module name="javax.api"/>
|
||||||
|
<module name="javax.transaction.api"/>
|
||||||
|
</dependencies>
|
||||||
|
</module>
|
||||||
|
----
|
||||||
|
|
||||||
|
The module name should match the directory structure of your module. So, _org/postgresql_ maps to `org.postgresql`. The
|
||||||
|
`resource-root path` attribute should specify the JAR filename of the driver. The rest are just the normal dependencies that
|
||||||
|
any JDBC driver JAR would have.
|
||||||
|
|
||||||
|
=== Declare and Load JDBC Driver
|
||||||
|
|
||||||
|
The next thing you have to do is declare your newly packaged JDBC driver into your deployment profile so that it loads and becomes
|
||||||
|
available when the server boots up. Where you perform this action depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>. If you're
|
||||||
|
deploying in standard mode, edit _.../standalone/configuration/standalone.xml_. If you're deploying in standard clustering
|
||||||
|
mode, edit _.../standalone/configuration/standalone-ha.xml_. If you're deploying in domain mode, edit
|
||||||
|
_.../domain/configuration/domain.xml_. In domain mode, you'll need to make sure you edit the profile you are using: either
|
||||||
|
`auth-server-standalone` or `auth-server-clustered`
|
||||||
|
|
||||||
|
Within the profile, search for the `drivers` XML block within the `datasources` subsystem. You should see
|
||||||
|
a pre-defined driver declared for the H2 JDBC driver. This is where you'll declare the JDBC driver for your external
|
||||||
|
database.
|
||||||
|
|
||||||
|
.JDBC Drivers
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
|
||||||
|
<datasources>
|
||||||
|
...
|
||||||
|
<drivers>
|
||||||
|
<driver name="h2" module="com.h2database.h2">
|
||||||
|
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
|
||||||
|
</driver>
|
||||||
|
</drivers>
|
||||||
|
</datasources>
|
||||||
|
</subsystem>
|
||||||
|
----
|
||||||
|
|
||||||
|
Within the `drivers` XML block you'll need to declare an additional JDBC driver. It needs to have a `name` which
|
||||||
|
you can choose to be anything you want. You specify the `module` attribute which points to the `module` package you
|
||||||
|
created earlier for the driver JAR. Finally
|
||||||
|
you have to specify the driver's Java class. Here's an example of installing PostgreSQL driver that lives in the module
|
||||||
|
example defined earlier in this chapter.
|
||||||
|
|
||||||
|
|
||||||
|
.Declare Your JDBC Drivers
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
|
||||||
|
<datasources>
|
||||||
|
...
|
||||||
|
<drivers>
|
||||||
|
<driver name="postgresql" module="org.postgresql">
|
||||||
|
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
|
||||||
|
</driver>
|
||||||
|
<driver name="h2" module="com.h2database.h2">
|
||||||
|
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
|
||||||
|
</driver>
|
||||||
|
</drivers>
|
||||||
|
</datasources>
|
||||||
|
</subsystem>
|
||||||
|
----
|
|
@ -0,0 +1,64 @@
|
||||||
|
|
||||||
|
=== Unicode Considerations for Databases
|
||||||
|
|
||||||
|
Database schema in {{book.project.name}} only accounts for Unicode strings in the following special fields:
|
||||||
|
|
||||||
|
* Realms: display name, HTML display name
|
||||||
|
* Federation Providers: display name
|
||||||
|
* Users: username, given name, last name, attribute names and values
|
||||||
|
* Groups: name, attribute names and values
|
||||||
|
* Roles: name
|
||||||
|
* Descriptions of objects
|
||||||
|
|
||||||
|
Otherwise, characters are limited to those contained in database encoding which is often 8-bit. However, for some
|
||||||
|
database systems, it is possible to enable UTF-8 encoding of Unicode characters and use full Unicode character set in all
|
||||||
|
text fields. Often, this is counterbalanced by shorter maximum length of the strings than in case of 8-bit encodings.
|
||||||
|
|
||||||
|
Some of the databases require special settings to database and/or JDBC driver to be able to handle Unicode characters.
|
||||||
|
Please find the settings for your database below. Note that if a database is listed here, it can still work properly
|
||||||
|
provided it handles UTF-8 encoding properly both on the level of database and JDBC driver.
|
||||||
|
|
||||||
|
Technically, the key criterion for Unicode support for all fields is whether the database allows setting of Unicode
|
||||||
|
character set for `VARCHAR` and `CHAR` fields. If yes, there is a high chance that Unicode will be plausible, usually at
|
||||||
|
the expense of field length. If it only supports Unicode in `NVARCHAR` and `NCHAR` fields, Unicode support for all text
|
||||||
|
fields is unlikely as Keycloak schema uses `VARCHAR` and `CHAR` fields extensively.
|
||||||
|
|
||||||
|
==== Oracle Database
|
||||||
|
|
||||||
|
Unicode characters are properly handled provided the database was created with Unicode support in `VARCHAR` and `CHAR`
|
||||||
|
fields (e.g. by using `AL32UTF8` character set as the database character set). No special settings is needed for JDBC
|
||||||
|
driver.
|
||||||
|
|
||||||
|
If the database character set is not Unicode, then to use Unicode characters in the special fields, the JDBC driver needs
|
||||||
|
to be configured with the connection property `oracle.jdbc.defaultNChar` set to `true`. It might be wise, though not
|
||||||
|
strictly necessary, to also set the `oracle.jdbc.convertNcharLiterals` connection property to `true`. These properties
|
||||||
|
can be set either as system properties or as connection properties. Please note that setting `oracle.jdbc.defaultNChar`
|
||||||
|
may have negative impact on performance. For details, please refer to Oracle JDBC driver configuration documentation.
|
||||||
|
|
||||||
|
==== Microsoft SQL Server Database
|
||||||
|
|
||||||
|
Unicode characters are properly handled only for the special fields. No special settings of JDBC driver or database is
|
||||||
|
necessary.
|
||||||
|
|
||||||
|
==== IBM DB2 Database
|
||||||
|
|
||||||
|
Unicode characters are properly handled for all fields, length reduction applies to non-special fields. No special
|
||||||
|
settings of JDBC driver or database is necessary.
|
||||||
|
|
||||||
|
==== MySQL Database
|
||||||
|
|
||||||
|
Unicode characters are properly handled provided the database was created with Unicode support in `VARCHAR` and `CHAR`
|
||||||
|
fields in the `CREATE DATABASE` command (e.g. by using `utf8` character set as the default database character set in
|
||||||
|
MySQL 5.5. Please note that `utf8mb4` character set does not work due to different storage requirements to `utf8`
|
||||||
|
character set footnote:[Tracked as https://issues.jboss.org/browse/KEYCLOAK-3873]). Note that in this case, length
|
||||||
|
restriction to non-special fields does not apply because columns are created to accomodate given amount of characters,
|
||||||
|
not bytes. If the database default character set does not allow storing Unicode, only the special fields allow storing
|
||||||
|
Unicode values.
|
||||||
|
|
||||||
|
At the side of JDBC driver settings, it is necessary to add a connection property `characterEncoding=UTF-8` to the JDBC
|
||||||
|
connection settings.
|
||||||
|
|
||||||
|
==== PostgreSQL Database
|
||||||
|
|
||||||
|
Unicode is supported when the database character set is `UTF8`. In that case, Unicode characters can be used in any
|
||||||
|
field, there is no reduction of field length for non-special fields. No special settings of JDBC driver is necessary.
|
5
server_installation/topics/installation.adoc
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
== Installation
|
||||||
|
|
||||||
|
Installing {{book.project.name}} is as simple as downloading it and unzipping it. This chapter reviews system requirements
|
||||||
|
as well as the directory structure of the distribution.
|
30
server_installation/topics/installation/directory-structure.adoc
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
=== Distribution Directory Structure
|
||||||
|
|
||||||
|
This chapter walks you through the directory structure of the server distribution.
|
||||||
|
|
||||||
|
.distribution directory structure
|
||||||
|
image:../../{{book.images}}/files.png[alt="distribution"]
|
||||||
|
|
||||||
|
Let's examine the purpose of some of the directories:
|
||||||
|
|
||||||
|
_bin/_::
|
||||||
|
This contains various scripts to either boot the server or perform some other management action on the server.
|
||||||
|
|
||||||
|
_domain/_::
|
||||||
|
This contains configuration files and working directory when running {{book.project.name}} in <<fake/../../operating-mode/domain.adoc#_domain-mode,domain mode>>.
|
||||||
|
|
||||||
|
_modules/_::
|
||||||
|
These are all the Java libraries used by the server.
|
||||||
|
|
||||||
|
{% if book.community %}
|
||||||
|
_providers/_::
|
||||||
|
If you are writing extensions to keycloak, you can put your extensions here. See the link:{{book.developerguide.link}}[{{book.developerguide.name}}] for more information on this.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
_standalone/_::
|
||||||
|
This contains configuration files and working directory when running {{book.project.name}} in <<fake/../../operating-mode/standalone.adoc#_standalone-mode,standalone mode>>.
|
||||||
|
|
||||||
|
_themes/_::
|
||||||
|
This directory contains all the html, style sheets, javascript files, and images used to display any UI screen displayed by the server.
|
||||||
|
Here you can modify an existing theme or create your own. See the link:{{book.developerguide.link}}[{{book.developerguide.name}}] for more information on this.
|
27
server_installation/topics/installation/distribution-files-community.adoc
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
=== Installing Distribution Files
|
||||||
|
|
||||||
|
The Keycloak Server has three downloadable distributions:
|
||||||
|
|
||||||
|
* 'keycloak-{{book.project.version}}.[zip|tar.gz]'
|
||||||
|
* 'keycloak-overlay-{{book.project.version}}.[zip|tar.gz]'
|
||||||
|
* 'keycloak-demo-{{book.project.version}}.[zip|tar.gz]'
|
||||||
|
|
||||||
|
The 'keycloak-{{book.project.version}}.[zip|tar.gz]' file is the server only distribution. It contains nothing other than the scripts and binaries
|
||||||
|
to run the Keycloak Server. To unpack this file just run your operating system's `unzip` or `gunzip` and `tar` utilities.
|
||||||
|
|
||||||
|
The 'keycloak-overlay-{{book.project.version}}.[zip|tar.gz]' file is a Wildfly Service Pack that allows you to install Keycloak Server on top of an existing
|
||||||
|
Wildfly or JBoss EAP distribution. We suggest that you do not use this distribution unless you want to install on top of the latest JBoss EAP distribution. We do not support
|
||||||
|
users that want to run their applications and Keycloak on the same server instance. To install the Keycloak Service Pack, just unzip it in the root directory
|
||||||
|
of your JBoss EAP distribution.
|
||||||
|
|
||||||
|
The 'keycloak-demo-{{book.project.version}}.[zip|tar.gz]' contains the server binaries, all documentation and all examples. It is preconfigured with both the
|
||||||
|
OIDC and SAML client application adapters and can deploy any of the distribution examples out of the box with no configuration. This distribution is only
|
||||||
|
recommended for those that want to test drive Keycloak. We do not support users that run the demo distribution in production.
|
||||||
|
|
||||||
|
To unpack of these files run the `unzip` or `gunzip` and `tar` utilities.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
16
server_installation/topics/installation/distribution-files-product.adoc
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
=== Installing Distribution Files
|
||||||
|
|
||||||
|
The {{book.project.name}} Server is contained in one distribution file:
|
||||||
|
|
||||||
|
* 'rh-sso-{{book.project.version}}.[zip|tar.gz]'
|
||||||
|
|
||||||
|
The 'rh-sso-{{book.project.version}}.[zip|tar.gz]' file is the server only distribution. It contains nothing other than the scripts and binaries
|
||||||
|
to run the {{book.project.name}} Server.
|
||||||
|
|
||||||
|
To unpack of these files run the `unzip` or `gunzip` and `tar` utilities.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
18
server_installation/topics/installation/system-requirements.adoc
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
=== System Requirements
|
||||||
|
|
||||||
|
These are the requirements to run the {{book.project.name}} authentication server:
|
||||||
|
|
||||||
|
* Can run on any operating system that runs Java
|
||||||
|
* Java 8 JDK
|
||||||
|
* zip or gzip and tar
|
||||||
|
* At least 512M of RAM
|
||||||
|
* At least 1G of diskspace
|
||||||
|
* A shared external database like Postgres, MySql, Oracle, etc. {{book.project.name}} requires an external shared
|
||||||
|
database if you want to run in a cluster. Please see the <<fake/../../database.adoc#_database,database configuration>> section of this guide for more information.
|
||||||
|
* Network multicast support on your machine if you want to run in a cluster. {{book.project.name}} can
|
||||||
|
be clustered without multicast, but this requires a bunch of configuration changes. Please see
|
||||||
|
the <<fake/../../clustering.adoc#_clustering,clustering>> section of this guide for more information.
|
||||||
|
* On Linux, it is recommended to use `/dev/urandom` as a source of random data to prevent {{book.project.name}} hanging due to lack of available
|
||||||
|
entropy, unless `/dev/random` usage is mandated by your security policy. To achieve that on Oracle JDK 8 and OpenJDK 8, set the `java.security.egd`
|
||||||
|
system property on startup to `file:/dev/urandom`.
|
49
server_installation/topics/manage.adoc
Executable file
|
@ -0,0 +1,49 @@
|
||||||
|
[[_app_server_cli]]
|
||||||
|
|
||||||
|
== Manage Configuration at Runtime
|
||||||
|
|
||||||
|
In the upcoming chapters, you'll often be provided two options for applying application server configuration changes to your deployment. You'll be
|
||||||
|
shown how to edit the _standalone.xml_ or _domain.xml_ directly. This must be done when the server (or servers) are offline.
|
||||||
|
Additionally, you may be shown how to apply config changes on a running server using the app server's command line interface ({{book.appserver.name}} CLI). This chapter discusses
|
||||||
|
how you will do this.
|
||||||
|
|
||||||
|
|
||||||
|
=== Start the {{book.appserver.name}} CLI
|
||||||
|
|
||||||
|
To start the {{book.appserver.name}} CLI, you need to run the `jboss-cli` script.
|
||||||
|
|
||||||
|
.Linux/Unix
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ .../bin/jboss-cli.sh
|
||||||
|
----
|
||||||
|
|
||||||
|
.Windows
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
> ...\bin\jboss-cli.bat
|
||||||
|
----
|
||||||
|
|
||||||
|
This will bring you to a prompt like this:
|
||||||
|
|
||||||
|
.Prompt
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
[disconnected /]
|
||||||
|
----
|
||||||
|
|
||||||
|
There's a few commands you can execute without a running standalone server or domain controller, but usually you will
|
||||||
|
have to have those services booted up before you can execute CLI commands. To connect to a running server simply
|
||||||
|
execute the `connect` command.
|
||||||
|
|
||||||
|
.connect
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
[disconnected /] connect
|
||||||
|
connect
|
||||||
|
[domain@localhost:9990 /]
|
||||||
|
----
|
||||||
|
|
||||||
|
You may be thinking to yourself, "I didn't enter in any username or password!". If you run `jboss-cli` on the same machine
|
||||||
|
as your running standalone server or domain controller and your account has appropriate file permissions, you do not have
|
||||||
|
to setup or enter in a admin username and password. See the link:{{book.appserver.admindoc.link}}[_{{book.appserver.admindoc.name}}_] for more details on how to make things more secure if you are uncomfortable with that setup.
|
121
server_installation/topics/mongo.adoc
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
|
||||||
|
[[_mongo]]
|
||||||
|
|
||||||
|
== Mongo DB Setup
|
||||||
|
|
||||||
|
You are not stuck with using a RDBMS for persisting data. {{book.project.name}}
|
||||||
|
provides a http://www.mongodb.com[MongoDB] based model implementation.
|
||||||
|
To configure {{book.project.name}} to use Mongo, you need to edit the `standalone.xml`,
|
||||||
|
`standalone-ha.xml`, or `domain.xml` file in your distribution. The location of this file
|
||||||
|
depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>.
|
||||||
|
|
||||||
|
Open the `standalone.xml`, `standalone-ha.xml`, or `domain.xml` file. Look for the following XML snippets and replace all the _jpa_ providers with _mongo_ . This is the area you will be modifying
|
||||||
|
to use Mongo.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="eventsStore">
|
||||||
|
<default-provider>jpa</default-provider>
|
||||||
|
<provider name="jpa" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="exclude-events" value="["REFRESH_TOKEN"]"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
<spi name="realm">
|
||||||
|
<default-provider>jpa</default-provider>
|
||||||
|
</spi>
|
||||||
|
<spi name="user">
|
||||||
|
<default-provider>jpa</default-provider>
|
||||||
|
</spi>
|
||||||
|
<spi name="userFederatedStorage">
|
||||||
|
<default-provider>jpa</default-provider>
|
||||||
|
<provider name="jpa" enabled="true"/>
|
||||||
|
</spi>
|
||||||
|
<spi name="userSessionPersister">
|
||||||
|
<default-provider>jpa</default-provider>
|
||||||
|
</spi>
|
||||||
|
<spi name="authorizationPersister">
|
||||||
|
<default-provider>jpa</default-provider>
|
||||||
|
</spi>
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Change that XML snippet to use Mongo:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="eventsStore">
|
||||||
|
<default-provider>mongo</default-provider>
|
||||||
|
<provider name="mongo" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="exclude-events" value="["REFRESH_TOKEN"]"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
<spi name="realm">
|
||||||
|
<default-provider>mongo</default-provider>
|
||||||
|
</spi>
|
||||||
|
<spi name="user">
|
||||||
|
<default-provider>mongo</default-provider>
|
||||||
|
</spi>
|
||||||
|
<spi name="userFederatedStorage">
|
||||||
|
<default-provider>mongo</default-provider>-->
|
||||||
|
<provider name="mongo" enabled="true"/>
|
||||||
|
</spi>
|
||||||
|
<spi name="userSessionPersister">
|
||||||
|
<default-provider>mongo</default-provider>
|
||||||
|
</spi>
|
||||||
|
<spi name="authorizationPersister">
|
||||||
|
<default-provider>mongo</default-provider>
|
||||||
|
</spi>
|
||||||
|
----
|
||||||
|
After that, add the snippet like this where you can configure details about your Mongo database:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="connectionsMongo">
|
||||||
|
<provider name="default" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="host" value="127.0.0.1"/>
|
||||||
|
<property name="port" value="27017"/>
|
||||||
|
<property name="db" value="keycloak"/>
|
||||||
|
<property name="connectionsPerHost" value="100"/>
|
||||||
|
<property name="migrationStrategy" value="update"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
----
|
||||||
|
All configuration options are optional.
|
||||||
|
Default values for host and port are localhost and 27017.
|
||||||
|
Default name of database is `keycloak` . You can also specify properties `user` and `password` if you want authenticate against your MongoDB.
|
||||||
|
If user and password are not specified, {{book.project.name}} will connect unauthenticated to your MongoDB.
|
||||||
|
|
||||||
|
Finally there is set of optional configuration options, which can be used to specify connection-pooling capabilities of Mongo client.
|
||||||
|
Supported int options are: `connectionsPerHost`, `threadsAllowedToBlockForConnectionMultiplier`, `maxWaitTime`, `connectTimeout` `socketTimeout`.
|
||||||
|
Supported boolean options are: `socketKeepAlive`, `autoConnectRetry`.
|
||||||
|
Supported long option is `maxAutoConnectRetryTime`.
|
||||||
|
See http://api.mongodb.org/java/2.11.4/com/mongodb/MongoClientOptions.html[Mongo documentation] for details about those options and their default values.
|
||||||
|
|
||||||
|
Alternatively, you can configure MongoDB using a MongoDB http://docs.mongodb.org/manual/reference/connection-string/[connection URI].
|
||||||
|
In this case, you define all information concerning the connection and authentication within the URI, as described in the MongoDB documentation.
|
||||||
|
Please note that the database specified within the URI is only used for authentication.
|
||||||
|
To change the database used by {{book.project.name}} you have to set `db` property as before.
|
||||||
|
Therefore, a configuration like the following
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="connectionsMongo">
|
||||||
|
<provider name="default" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="uri" value="mongodb://user:password@127.0.0.1/authentication"/>
|
||||||
|
<property name="db" value="keycloak"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
----
|
||||||
|
will authenticate the user against the authentication database, but store all {{book.project.name}} related data in the keycloak database.
|
||||||
|
|
||||||
|
=== MongoDB Replica Sets
|
||||||
|
|
||||||
|
In order to use a mongo replica set for {{book.project.name}}, one has to use URI based configuration, which supports the definition of replica sets out of the box: `mongodb://host1:27017,host2:27017,host3:27017/`.
|
21
server_installation/topics/network.adoc
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
[[_network]]
|
||||||
|
|
||||||
|
== Network Setup
|
||||||
|
|
||||||
|
{{book.project.name}} can run out of the box with some networking limitations. For one, all network endpoints bind to `localhost`
|
||||||
|
so the auth server is really only usable on one local machine. For HTTP based connections, it does not use default ports
|
||||||
|
like 80 and 443. HTTPS/SSL is not configured out of the box and without it, {{book.project.name}} has many security
|
||||||
|
vulnerabilities.
|
||||||
|
Finally, {{book.project.name}}
|
||||||
|
may often need to make secure SSL and HTTPS connections to external servers and thus need a trust store set up so that endpoints can
|
||||||
|
be validated correctly. This chapter discusses all of these things.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
53
server_installation/topics/network/bind-address.adoc
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
[[_bind-address]]
|
||||||
|
|
||||||
|
=== Bind Addresses
|
||||||
|
|
||||||
|
By default {{book.project.name}} binds to the localhost loopback address `127.0.0.1`. That's not a very useful default if
|
||||||
|
you want the authentication server available on your network. Generally, what we recommend is that you deploy a reverse proxy
|
||||||
|
or load balancer on a public network and route traffic to individual {{book.project.name}} server instances on a private network.
|
||||||
|
In either case though, you still need to set up your network interfaces to bind to something other than `localhost`.
|
||||||
|
|
||||||
|
Setting the bind address is quite easy and can be done on the command line with either the _standalone.sh_ or
|
||||||
|
_domain.sh_ boot scripts discussed in the <<fake/../../operating-mode.adoc#_operating-mode, Choosing an Operating Mode>> chapter.
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ standalone.sh -b 192.168.0.5
|
||||||
|
----
|
||||||
|
|
||||||
|
The `-b` switch sets the IP bind address for any public interfaces.
|
||||||
|
|
||||||
|
Alternatively, if you don't want to set the bind address at the command line, you can edit the profile configuration of your deployment.
|
||||||
|
Open up the profile configuration file (_standalone.xml_ or _domain.xml_ depending on your
|
||||||
|
<<fake/../../operating-mode.adoc#_operating-mode, operating mode>>) and look for the `interfaces` XML block.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<interfaces>
|
||||||
|
<interface name="management">
|
||||||
|
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
|
||||||
|
</interface>
|
||||||
|
<interface name="public">
|
||||||
|
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
|
||||||
|
</interface>
|
||||||
|
</interfaces>
|
||||||
|
----
|
||||||
|
|
||||||
|
The `public` interface corresponds to subsystems creating sockets that are available publicly. An example of one
|
||||||
|
of these subsystems is the web layer which serves up the authentication endpoints of {{book.project.name}}. The `management`
|
||||||
|
interface corresponds to sockets opened up by the management layer of the {{book.appserver.name}}. Specifically the sockets
|
||||||
|
which allow you to use the `jboss-cli.sh` command line interface and the {{book.appserver.name}} web console.
|
||||||
|
|
||||||
|
In looking at the `public` interface you see that it has a special string `${jboss.bind.address:127.0.0.1}`. This string
|
||||||
|
denotes a value `127.0.0.1` that can be overriden on the command line by setting a Java system property, i.e.:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ domain.sh -Djboss.bind.address=192.168.0.5
|
||||||
|
----
|
||||||
|
|
||||||
|
The `-b` is just a shorthand notation for this command. So, you can either change the bind address value directly in the profile config, or change it on the command line when
|
||||||
|
you boot up.
|
||||||
|
|
||||||
|
NOTE: There are many more options available when setting up `interface` definitions. For more information, see link:{{book.appserver.network.link}}[the network interface] in the _{{book.appserver.network.name}}_.
|
149
server_installation/topics/network/https.adoc
Executable file
|
@ -0,0 +1,149 @@
|
||||||
|
|
||||||
|
=== Setting up HTTPS/SSL
|
||||||
|
|
||||||
|
WARNING: {{book.project.name}} is not set up by default to handle SSL/HTTPS.
|
||||||
|
It is highly recommended that you either enable SSL on the {{book.project.name}} server itself or on a reverse proxy in front of the {{book.project.name}} server.
|
||||||
|
|
||||||
|
This default behavior is defined by the SSL/HTTPS mode of each {{book.project.name}} realm. This is discussed in more detail in the
|
||||||
|
link:{{book.adminguide.link}}[{{book.adminguide.name}}], but let's give some context and a brief overview of these modes.
|
||||||
|
|
||||||
|
external requests::
|
||||||
|
{{book.project.name}} can run out of the box without SSL so long as you stick to private IP addresses like `localhost`, `127.0.0.1`, `10.0.x.x`, `192.168.x.x`, and `172..16.x.x`.
|
||||||
|
If you don’t have SSL/HTTPS configured on the server or you try to access {{book.project.name}} over HTTP from a non-private IP adress you will get an error.
|
||||||
|
|
||||||
|
none::
|
||||||
|
{{book.project.name}} does not require SSL. This should really only be used in development when you are playing around with things.
|
||||||
|
|
||||||
|
all requests::
|
||||||
|
{{book.project.name}} requires SSL for all IP addresses.
|
||||||
|
|
||||||
|
The SSL mode for each realm can be configured in the {{book.project.name}} admin console.
|
||||||
|
|
||||||
|
==== Enabling SSL/HTTPS for the {{book.project.name}} Server
|
||||||
|
|
||||||
|
If you are not using a reverse proxy or load balancer to handle HTTPS traffic for you, you'll need to enable HTTPS
|
||||||
|
for the {{book.project.name}} server. This involves
|
||||||
|
|
||||||
|
. Obtaining or generating a keystore that contains the private key and certificate for SSL/HTTP traffic
|
||||||
|
. Configuring the {{book.project.name}} server to use this keypair and certificate.
|
||||||
|
|
||||||
|
===== Creating the Certificate and Java Keystore
|
||||||
|
|
||||||
|
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 {{book.project.name}} Server to.
|
||||||
|
|
||||||
|
====== Self Signed Certificate
|
||||||
|
|
||||||
|
In development, you will probably not have a third party signed certificate available to test a {{book.project.name}} deployment so you'll need to generate a self-signed one
|
||||||
|
using the `keytool` utility that comes with the Java JDK.
|
||||||
|
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
$ 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
|
||||||
|
----
|
||||||
|
|
||||||
|
You should answer `What is your first and last name ?` question with the DNS name of the machine you're installing the server on.
|
||||||
|
For testing purposes, `localhost` should be used.
|
||||||
|
After executing this command, the `keycloak.jks` file will be generated in the same directory as you executed the `keytool` command in.
|
||||||
|
|
||||||
|
If you want a third-party signed certificate, but don't have one, you can obtain one for free at http://cacert.org[cacert.org].
|
||||||
|
You'll have to do a little set up first before doing this though.
|
||||||
|
|
||||||
|
The first thing to do is generate a Certificate Request:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
$ keytool -certreq -alias yourdomain -keystore keycloak.jks > keycloak.careq
|
||||||
|
----
|
||||||
|
|
||||||
|
Where `yourdomain` is a DNS name for which this certificate is generated for.
|
||||||
|
Keytool generates the request:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
-----BEGIN NEW CERTIFICATE REQUEST-----
|
||||||
|
MIIC2jCCAcICAQAwZTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMREwDwYDVQQHEwhXZXN0Zm9y
|
||||||
|
ZDEQMA4GA1UEChMHUmVkIEhhdDEQMA4GA1UECxMHUmVkIEhhdDESMBAGA1UEAxMJbG9jYWxob3N0
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr7kck2TaavlEOGbcpi9c0rncY4HhdzmY
|
||||||
|
Ax2nZfq1eZEaIPqI5aTxwQZzzLDK9qbeAd8Ji79HzSqnRDxNYaZu7mAYhFKHgixsolE3o5Yfzbw1
|
||||||
|
29RvyeUVe+WZxv5oo9wolVVpdSINIMEL2LaFhtX/c1dqiqYVpfnvFshZQaIg2nL8juzZcBjj4as
|
||||||
|
H98gIS7khql/dkZKsw9NLvyxgJvp7PaXurX29fNf3ihG+oFrL22oFyV54BWWxXCKU/GPn61EGZGw
|
||||||
|
Ft2qSIGLdctpMD1aJR2bcnlhEjZKDksjQZoQ5YMXaAGkcYkG6QkgrocDE2YXDbi7GIdf9MegVJ35
|
||||||
|
2DQMpwIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUQwlZJBA+fjiDdiVzaO9vrE/i
|
||||||
|
n2swDQYJKoZIhvcNAQELBQADggEBAC5FRvMkhal3q86tHPBYWBuTtmcSjs4qUm6V6f63frhveWHf
|
||||||
|
PzRrI1xH272XUIeBk0gtzWo0nNZnf0mMCtUBbHhhDcG82xolikfqibZijoQZCiGiedVjHJFtniDQ
|
||||||
|
9bMDUOXEMQ7gHZg5q6mJfNG9MbMpQaUVEEFvfGEQQxbiFK7hRWU8S23/d80e8nExgQxdJWJ6vd0X
|
||||||
|
MzzFK6j4Dj55bJVuM7GFmfdNC52pNOD5vYe47Aqh8oajHX9XTycVtPXl45rrWAH33ftbrS8SrZ2S
|
||||||
|
vqIFQeuLL3BaHwpl3t7j2lMWcK1p80laAxEASib/fAwrRHpLHBXRcq6uALUOZl4Alt8=
|
||||||
|
-----END NEW CERTIFICATE REQUEST-----
|
||||||
|
----
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
$ keytool -import -keystore keycloak.jks -file root.crt -alias root
|
||||||
|
----
|
||||||
|
|
||||||
|
Last step is to import your new CA generated certificate to your keystore:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
$ keytool -import -alias yourdomain -keystore keycloak.jks -file your-certificate.cer
|
||||||
|
----
|
||||||
|
|
||||||
|
===== Configure {{book.project.name}} to Use the Keystore
|
||||||
|
|
||||||
|
Now that you have a Java keystore with the appropriate certificates, you need to configure your {{book.project.name}} installation to use it.
|
||||||
|
First step is to move the keystore file to the _configuration/_ directory of your deployment and to edit the _standalone.xml_, _standalone-ha.xml_ or _domain.xml_ file to use
|
||||||
|
the keystore and enable HTTPS. (See <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>).
|
||||||
|
|
||||||
|
In the standalone or domain configuration file, search for the `security-realms` element and add:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
<security-realm name="UndertowRealm">
|
||||||
|
<server-identities>
|
||||||
|
<ssl>
|
||||||
|
<keystore path="keycloak.jks" relative-to="jboss.server.config.dir" keystore-password="secret" />
|
||||||
|
</ssl>
|
||||||
|
</server-identities>
|
||||||
|
</security-realm>
|
||||||
|
----
|
||||||
|
|
||||||
|
Find the element `server name="default-server"` (it's a child element of `subsystem xmlns="urn:jboss:domain:undertow:`) and add:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
<subsystem xmlns="urn:jboss:domain:undertow:3.0">
|
||||||
|
<buffer-cache name="default"/>
|
||||||
|
<server name="default-server">
|
||||||
|
<https-listener name="https" socket-binding="https" security-realm="UndertowRealm"/>
|
||||||
|
...
|
||||||
|
</subsystem>
|
||||||
|
----
|
122
server_installation/topics/network/outgoing.adoc
Executable file
|
@ -0,0 +1,122 @@
|
||||||
|
|
||||||
|
=== Outgoing HTTP Requests
|
||||||
|
|
||||||
|
The {{book.project.name}} server often needs to make non-browser HTTP requests to the applications and services it secures.
|
||||||
|
The auth server manages these outgoing connections by maintaining an HTTP client connection pool. There are some things
|
||||||
|
you'll need to configure in `standalone.xml`, `standalone-ha.xml`, or `domain.xml`. The location of this file
|
||||||
|
depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>.
|
||||||
|
|
||||||
|
.HTTP client Config example
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="connectionsHttpClient">
|
||||||
|
<provider name="default" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="connection-pool-size" value="256"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
----
|
||||||
|
Possible configuration options are:
|
||||||
|
|
||||||
|
establish-connection-timeout-millis::
|
||||||
|
Timeout for establishing a socket connection.
|
||||||
|
|
||||||
|
socket-timeout-millis::
|
||||||
|
If an outgoing request does not receive data for this amount of time, timeout the connection.
|
||||||
|
|
||||||
|
connection-pool-size::
|
||||||
|
How many connections can be in the pool (128 by default).
|
||||||
|
|
||||||
|
max-pooled-per-route::
|
||||||
|
How many connections can be pooled per host (64 by default).
|
||||||
|
|
||||||
|
connection-ttl-millis::
|
||||||
|
Maximum connection time to live in milliseconds.
|
||||||
|
Not set by default.
|
||||||
|
|
||||||
|
max-connection-idle-time-millis::
|
||||||
|
Maximum time the connection might stay idle in the connection pool (900 seconds by default). Will start background cleaner thread of Apache HTTP client.
|
||||||
|
Set to -`1` to disable this checking and the background thread.
|
||||||
|
|
||||||
|
disable-cookies::
|
||||||
|
`true` by default.
|
||||||
|
When set to true, this will disable any cookie caching.
|
||||||
|
|
||||||
|
client-keystore::
|
||||||
|
This is the file path to a Java keystore file.
|
||||||
|
This keystore contains client certificate for two-way SSL.
|
||||||
|
|
||||||
|
client-keystore-password::
|
||||||
|
Password for the client keystore.
|
||||||
|
This is _REQUIRED_ if `client-keystore` is set.
|
||||||
|
|
||||||
|
client-key-password::
|
||||||
|
Password for the client's key.
|
||||||
|
This is _REQUIRED_ if `client-keystore` is set.
|
||||||
|
|
||||||
|
[[_truststore]]
|
||||||
|
==== Outgoing HTTPS Request Truststore
|
||||||
|
|
||||||
|
When {{book.project.name}} invokes on remote HTTPS endpoints, it has to validate the remote server's certificate in order to ensure it is connecting to a trusted server.
|
||||||
|
This is necessary in order to prevent man-in-the-middle attacks. The certificates of these remote server's or the CA that signed these
|
||||||
|
certificates must be put in a truststore. This truststore is managed by the {{book.project.name}} server.
|
||||||
|
|
||||||
|
The truststore is used when connecting securely to identity brokers, LDAP identity providers, when sending emails, and for backchannel communication with client applications.
|
||||||
|
|
||||||
|
WARNING: By default, a truststore provider is not configured, and any https connections fall back to standard java truststore configuration as described in
|
||||||
|
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html[Java's JSSE Reference Guide]. If there is no trust
|
||||||
|
establised, then these outgoing HTTPS requests will fail.
|
||||||
|
|
||||||
|
You can use _keytool_ to create a new truststore file or add trusted host certificates to an existing one:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
$ keytool -import -alias HOSTDOMAIN -keystore truststore.jks -file host-certificate.cer
|
||||||
|
----
|
||||||
|
|
||||||
|
The truststore is configured within the `standalone.xml`,
|
||||||
|
`standalone-ha.xml`, or `domain.xml` file in your distribution. The location of this file
|
||||||
|
depends on your <<fake/../../operating-mode.adoc#_operating-mode, operating mode>>.
|
||||||
|
You can add your truststore configuration by using the following template:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<spi name="truststore">
|
||||||
|
<provider name="file" enabled="true">
|
||||||
|
<properties>
|
||||||
|
<property name="file" value="path to your .jks file containing public certificates"/>
|
||||||
|
<property name="password" value="password"/>
|
||||||
|
<property name="hostname-verification-policy" value="WILDCARD"/>
|
||||||
|
<property name="disabled" value="false"/>
|
||||||
|
</properties>
|
||||||
|
</provider>
|
||||||
|
</spi>
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Possible configuration options for this setting are:
|
||||||
|
|
||||||
|
file::
|
||||||
|
The path to a Java keystore file.
|
||||||
|
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.
|
||||||
|
This truststore file should only contain public certificates of your secured hosts.
|
||||||
|
This is _REQUIRED_ if `disabled` is not true.
|
||||||
|
|
||||||
|
password::
|
||||||
|
Password for the truststore.
|
||||||
|
This is _REQUIRED_ if `disabled` is not true.
|
||||||
|
|
||||||
|
hostname-verification-policy::
|
||||||
|
`WILDCARD` by default.
|
||||||
|
For HTTPS requests, this verifies the hostname of the server's certificate.
|
||||||
|
`ANY` means that the hostname is not verified. `WILDCARD` Allows wildcards in subdomain names i.e.
|
||||||
|
*.foo.com. `STRICT` CN must match hostname exactly.
|
||||||
|
|
||||||
|
disabled::
|
||||||
|
If true (default value), truststore configuration will be ignored, and certificate checking will fall back to JSSE configuration as described.
|
||||||
|
If set to false, you must configure `file`, and `password` for the truststore.
|
||||||
|
|
58
server_installation/topics/network/ports.adoc
Executable file
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
[[_ports]]
|
||||||
|
|
||||||
|
=== Socket Port Bindings
|
||||||
|
|
||||||
|
The ports opened for each socket have a pre-defined default that can be overriden at the command line or within configuration.
|
||||||
|
To illustrate this configuration, let's pretend you are running in <<fake/../../operating-mode/standalone.adoc#_standalone-mode,standalone mode>> and
|
||||||
|
open up the _.../standalone/configuration/standalone.xml_. Search for `socket-binding-group`.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||||
|
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
|
||||||
|
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
|
||||||
|
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
|
||||||
|
<socket-binding name="http" port="${jboss.http.port:8080}"/>
|
||||||
|
<socket-binding name="https" port="${jboss.https.port:8443}"/>
|
||||||
|
<socket-binding name="txn-recovery-environment" port="4712"/>
|
||||||
|
<socket-binding name="txn-status-manager" port="4713"/>
|
||||||
|
<outbound-socket-binding name="mail-smtp">
|
||||||
|
<remote-destination host="localhost" port="25"/>
|
||||||
|
</outbound-socket-binding>
|
||||||
|
</socket-binding-group>
|
||||||
|
----
|
||||||
|
|
||||||
|
`socket-bindings` define socket connections that will be opened by the server. These bindings specify the
|
||||||
|
`interface` (bind address) they use as well as what port number they will open. The ones you will be most interested in are:
|
||||||
|
|
||||||
|
http::
|
||||||
|
Defines the port used for {{book.project.name}} HTTP connections
|
||||||
|
https::
|
||||||
|
Defines the port used for {{book.project.name}} HTTPS connections
|
||||||
|
ajp::
|
||||||
|
This socket binding defines the port used for the AJP protocol. This protocol is used by Apache HTTPD server
|
||||||
|
in conjunction `mod-cluster` when you are using Apache HTTPD as a load balancer.
|
||||||
|
management-http::
|
||||||
|
Defines the HTTP connection used by {{book.appserver.name}} CLI and web console.
|
||||||
|
|
||||||
|
When running in <<fake/../../operating-mode/domain.adoc#_domain-mode,domain mode>> setting the socket configurations
|
||||||
|
is a bit trickier as the example _domain.xml_ file has multiple `socket-binding-groups` defined. If you scroll down
|
||||||
|
to the `server-group` definitions you can see what `socket-binding-group` is used for each `server-group`.
|
||||||
|
|
||||||
|
.domain socket bindings
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<server-groups>
|
||||||
|
<server-group name="load-balancer-group" profile="load-balancer">
|
||||||
|
...
|
||||||
|
<socket-binding-group ref="load-balancer-sockets"/>
|
||||||
|
</server-group>
|
||||||
|
<server-group name="auth-server-group" profile="auth-server-clustered">
|
||||||
|
...
|
||||||
|
<socket-binding-group ref="ha-sockets"/>
|
||||||
|
</server-group>
|
||||||
|
</server-groups>
|
||||||
|
----
|
||||||
|
|
||||||
|
NOTE: There are many more options available when setting up `socket-binding-group` definitions. For more information, see link:{{book.appserver.socket.link}}[the socket binding group] in the _{{book.appserver.socket.name}}_.
|
45
server_installation/topics/openshift.adoc
Executable file
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
[[_openshift]]
|
||||||
|
|
||||||
|
== Running {{book.project.name}} Server on OpenShift
|
||||||
|
|
||||||
|
{{book.project.name}} provides a OpenShift cartridge to make it easy to get it running on OpenShift.
|
||||||
|
If you don't already have an account or don't know how to create applications go to https://www.openshift.com/ first.
|
||||||
|
You can create the {{book.project.name}} instance either with the web tool or the command line tool, both approaches are described below.
|
||||||
|
|
||||||
|
WARNING: It's important that immediately after creating a {{book.project.name}} instance you open the `Administration Console` and login to reset the password.
|
||||||
|
If this is not done anyone can easily gain admin rights to your {{book.project.name}} instance.
|
||||||
|
|
||||||
|
=== Create {{book.project.name}} instance with the web tool
|
||||||
|
|
||||||
|
. Open https://openshift.redhat.com/app/console/applications and click on `Add Application`.
|
||||||
|
. Scroll down to the bottom of the page to find the `Code Anything` section.
|
||||||
|
. Insert `http://cartreflect-claytondev.rhcloud.com/github/keycloak/openshift-keycloak-cartridge` into the `URL to a cartridge definition` field and click on `Next`.
|
||||||
|
. Fill in the following form and click on `Create Application`.
|
||||||
|
. Click on `Continue to the application overview page`.
|
||||||
|
. Under the list of applications you should find your {{book.project.name}} instance and the status should be `Started`.
|
||||||
|
. Click on it to open the {{book.project.name}} servers homepage.
|
||||||
|
|
||||||
|
=== Create {{book.project.name}} instance with the command-line tool
|
||||||
|
|
||||||
|
. Run the following command from a terminal:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
rhc app create <APPLICATION NAME> http://cartreflect-claytondev.rhcloud.com/github/keycloak/openshift-keycloak-cartridge
|
||||||
|
----
|
||||||
|
|
||||||
|
. Replace `<APPLICATION NAME>` with the name you want (for example {{book.project.name}}).
|
||||||
|
|
||||||
|
Once the instance is created the rhc tool outputs details about it.
|
||||||
|
Open the returned `URL` in a browser to open the {{book.project.name}} servers homepage.
|
||||||
|
|
||||||
|
=== Next steps
|
||||||
|
|
||||||
|
The {{book.project.name}} servers homepage shows the {{book.project.name}} logo and `Welcome to {{book.project.name}}`.
|
||||||
|
There is also a link to the `Administration Console`.
|
||||||
|
Open that and log in using username `admin` and password `admin`.
|
||||||
|
On the first login you are required to change the password.
|
||||||
|
|
||||||
|
TIP: On OpenShift {{book.project.name}} has been configured to only accept requests over https.
|
||||||
|
If you try to use http you will be redirected to https.
|
12
server_installation/topics/operating-mode.adoc
Executable file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
[[_operating-mode]]
|
||||||
|
|
||||||
|
== Choosing an Operating Mode
|
||||||
|
|
||||||
|
Before deploying {{book.project.name}} in a production environment you need to decide which type of operating mode
|
||||||
|
you are going to use. Will you run {{book.project.name}} within a cluster? Do you want a centralized way to manage
|
||||||
|
your server configurations? Your choice of operating mode effects how you configure databases, configure caching and even how you boot the server.
|
||||||
|
|
||||||
|
TIP: The {{book.project.name}} is built on top of the {{book.appserver.name}} Application Server. This guide will only
|
||||||
|
go over the basics for deployment within a specific mode. If you want specific information on this, a better place
|
||||||
|
to go would be the link:{{book.appserver.admindoc.link}}[_{{book.appserver.admindoc.name}}_].
|
288
server_installation/topics/operating-mode/domain.adoc
Executable file
|
@ -0,0 +1,288 @@
|
||||||
|
|
||||||
|
[[_domain-mode]]
|
||||||
|
=== Domain Clustered Mode
|
||||||
|
|
||||||
|
Domain mode is a way to centrally manage and publish the configuration for your servers.
|
||||||
|
|
||||||
|
Running a cluster in standard mode can quickly become aggravating as the cluster grows in size. Every time you need
|
||||||
|
to make a configuration change, you have perform it on each node in the cluster. Domain mode solves this problem by providing
|
||||||
|
a central place to store and publish configuration. It can be quite complex to set up, but it is worth it in the end.
|
||||||
|
This capability is built into the {{book.appserver.name}} Application Server which {{book.project.name}} derives from.
|
||||||
|
|
||||||
|
NOTE: The guide will go over the very basics of domain mode. Detailed steps on how to set up domain mode in a cluster should be obtained from the
|
||||||
|
link:{{book.appserver.admindoc.link}}[_{{book.appserver.admindoc.name}}_].
|
||||||
|
|
||||||
|
Here are some of the basic concepts of running in domain mode.
|
||||||
|
|
||||||
|
domain controller::
|
||||||
|
The domain controller is a process that is responsible for storing, managing, and publishing the general configuration
|
||||||
|
for each node in the cluster. This process is the central point from which nodes in a cluster obtain their configuration.
|
||||||
|
|
||||||
|
host controller::
|
||||||
|
The host controller is responsible for managing server instances on a specific machine. You configure it to run
|
||||||
|
one or more server instances. The domain controller can also interact with the host controllers on each machine to
|
||||||
|
manage the cluster. To reduce the number of running process, a domain controller also acts as a host controller on
|
||||||
|
the machine it runs on.
|
||||||
|
|
||||||
|
domain profile::
|
||||||
|
A domain profile is a named set of configuration that can be used by a server to boot from. A domain controller
|
||||||
|
can define multiple domain profiles that are consumed by different servers.
|
||||||
|
|
||||||
|
server group::
|
||||||
|
A server group is a collection of servers. They are managed and configured as one. You can assign a domain profile to a server group and every service in that
|
||||||
|
group will use that domain profile as their configuration.
|
||||||
|
|
||||||
|
In domain mode, a domain controller is started on a master node. The configuration for the cluster resides in the domain controller.
|
||||||
|
Next a host controller is started on each machine in the cluster. Each host controller deployment configuration specifies how
|
||||||
|
many {{book.project.name}} server instances will be started on that machine. When the host controller boots up, it starts
|
||||||
|
as many {{book.project.name}} server instances as it was configured to do. These server instances pull their configuration
|
||||||
|
from the domain controller.
|
||||||
|
|
||||||
|
==== Domain Configuration
|
||||||
|
|
||||||
|
Various other chapters in this guide walk you through configuring various aspects like databases,
|
||||||
|
HTTP network connections, caches, and other infrastructure related things. While standalone mode uses the _standalone.xml_ file to configure these things,
|
||||||
|
domain mode uses the _.../domain/configuration/domain.xml_ configuration file. This is
|
||||||
|
where the domain profile and server group for the {{book.project.name}} server are defined.
|
||||||
|
|
||||||
|
|
||||||
|
.domain.xml
|
||||||
|
image:../../{{book.images}}/domain-file.png[]
|
||||||
|
|
||||||
|
WARNING: Any changes you make to this file while the domain controller is running will not take effect and may even be overwritten
|
||||||
|
by the server. Instead use the the command line scripting or the web console of {{book.appserver.name}}. See
|
||||||
|
the link:{{book.appserver.admindoc.link}}[_{{book.appserver.admindoc.name}}_] for more information.
|
||||||
|
|
||||||
|
Let's look at some aspects of this _domain.xml_ file. The `auth-server-standalone` and `auth-server-clustered` `profile` XML blocks are where you are going to make the bulk of your configuration decisions.
|
||||||
|
You'll be configuring things here like network connections, caches, and database connections.
|
||||||
|
|
||||||
|
|
||||||
|
.auth-server profile
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<profiles>
|
||||||
|
<profile name="auth-server-standalone">
|
||||||
|
...
|
||||||
|
</profile>
|
||||||
|
<profile name="auth-server-clustered">
|
||||||
|
...
|
||||||
|
</profile>
|
||||||
|
----
|
||||||
|
|
||||||
|
The `auth-server-standalone` profile is a non-clustered setup. The `auth-server-clustered` profile is the clustered setup.
|
||||||
|
|
||||||
|
If you scroll down further, you'll see various `socket-binding-groups` defined.
|
||||||
|
|
||||||
|
.socket-binding-groups
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<socket-binding-groups>
|
||||||
|
<socket-binding-group name="standard-sockets" default-interface="public">
|
||||||
|
...
|
||||||
|
</socket-binding-group>
|
||||||
|
<socket-binding-group name="ha-sockets" default-interface="public">
|
||||||
|
...
|
||||||
|
</socket-binding-group>
|
||||||
|
<!-- load-balancer-sockets should be removed in production systems and replaced with a better softare or hardare based one -->
|
||||||
|
<socket-binding-group name="load-balancer-sockets" default-interface="public">
|
||||||
|
...
|
||||||
|
</socket-binding-group>
|
||||||
|
</socket-binding-groups>
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
This config defines the default port mappings for various connectors that are opened with each
|
||||||
|
{{book.project.name}} server instance. Any value that contains `${...}` is a value that can be overriden on the command line
|
||||||
|
with the `-D` switch, i.e.
|
||||||
|
|
||||||
|
----
|
||||||
|
$ domain.sh -Djboss.http.port=80
|
||||||
|
----
|
||||||
|
|
||||||
|
The definition of the server group for {{book.project.name}} resides in the `server-groups` XML block. It specifies the domain profile
|
||||||
|
that is used (`default`) and also some default boot arguments for the Java VM when the host controller boots an instance. It also
|
||||||
|
binds a `socket-binding-group` to the server group.
|
||||||
|
|
||||||
|
.server group
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<server-groups>
|
||||||
|
<!-- load-balancer-group should be removed in production systems and replaced with a better softare or hardare based one -->
|
||||||
|
<server-group name="load-balancer-group" profile="load-balancer">
|
||||||
|
<jvm name="default">
|
||||||
|
<heap size="64m" max-size="512m"/>
|
||||||
|
</jvm>
|
||||||
|
<socket-binding-group ref="load-balancer-sockets"/>
|
||||||
|
</server-group>
|
||||||
|
<server-group name="auth-server-group" profile="auth-server-clustered">
|
||||||
|
<jvm name="default">
|
||||||
|
<heap size="64m" max-size="512m"/>
|
||||||
|
</jvm>
|
||||||
|
<socket-binding-group ref="ha-sockets"/>
|
||||||
|
</server-group>
|
||||||
|
</server-groups>
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
==== Host Controller Configuration
|
||||||
|
|
||||||
|
{{book.project.name}} comes with two host controller configuration files that reside in the _.../domain/configuration/_ directory:
|
||||||
|
_host-master.xml_ and _host-slave.xml_. _host-master.xml_ is configured to boot up a domain controller, a load balancer, and
|
||||||
|
one {{book.project.name}} server instance. _host-slave.xml_ is configured to talk to the domain controller and boot up
|
||||||
|
one {{book.project.name}} server instance.
|
||||||
|
|
||||||
|
NOTE: The load balancer is not a required service. It exists so that you can easily test drive clustering on your development
|
||||||
|
machine. While usable in production, you have the option of replacing it if you have a different hardware or software
|
||||||
|
based load balancer you want to use.
|
||||||
|
|
||||||
|
.Host Controller Config
|
||||||
|
image:../../{{book.images}}/host-files.png[]
|
||||||
|
|
||||||
|
To disable the load balancer server instance, edit _host-master.xml_ and comment out or remove the `"load-balancer"` entry.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<servers>
|
||||||
|
<!-- remove or comment out next line -->
|
||||||
|
<server name="load-balancer" group="loadbalancer-group"/>
|
||||||
|
...
|
||||||
|
</servers>
|
||||||
|
----
|
||||||
|
|
||||||
|
Another interesting thing to note about this file is the declaration of the authentication server instance. It has
|
||||||
|
a `port-offset` setting. Any network port defined in the _domain.xml_ `socket-binding-group` or the server group
|
||||||
|
will have the value of `port-offset` added to it. For this example domain setup we do this so that ports opened by
|
||||||
|
the load balancer server don't conflict with the authentication server instance that is started.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<servers>
|
||||||
|
...
|
||||||
|
<server name="server-one" group="auth-server-group" auto-start="true">
|
||||||
|
<socket-bindings port-offset="150"/>
|
||||||
|
</server>
|
||||||
|
</servers>
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Server Instance Working Directories
|
||||||
|
|
||||||
|
Each {{book.project.name}} server instance defined in your host files creates a working directory under _.../domain/servers/{SERVER NAME}_.
|
||||||
|
Additional configuration can be put there, and any temporary, log, or data files the server instance needs or creates go there too.
|
||||||
|
The structure of these per server directories ends up looking like any other {{book.appserver.name}} booted server.
|
||||||
|
|
||||||
|
.Working Directories
|
||||||
|
image:../../{{book.images}}/domain-server-dir.png[]
|
||||||
|
|
||||||
|
==== Domain Boot Script
|
||||||
|
|
||||||
|
When running the server in domain mode, there is a specific script you need to run to boot the server depending on your
|
||||||
|
operating system. These scripts live in the _bin/_ directory of the server distribution.
|
||||||
|
|
||||||
|
.Domain Boot Script
|
||||||
|
image:../../{{book.images}}/domain-boot-files.png[]
|
||||||
|
|
||||||
|
To boot the server:
|
||||||
|
|
||||||
|
.Linux/Unix
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ .../bin/domain.sh --host-config=host-master.xml
|
||||||
|
----
|
||||||
|
|
||||||
|
.Windows
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
> ...\bin\domain.bat --host-config=host-slave.xml
|
||||||
|
----
|
||||||
|
|
||||||
|
When running the boot script you will need pass in the host controlling configuration file you are going to use via the
|
||||||
|
`--host-config` switch.
|
||||||
|
|
||||||
|
[[_clustered-domain-example]]
|
||||||
|
==== Clustered Domain Example
|
||||||
|
|
||||||
|
You can test drive clustering using the out-of-the-box _domain.xml_ configuration. This example
|
||||||
|
domain is meant to run on one machine and boots up:
|
||||||
|
|
||||||
|
* a domain controller
|
||||||
|
* an HTTP load balancer
|
||||||
|
* 2 {{book.project.name}} server instances
|
||||||
|
|
||||||
|
To simulate running a cluster on two machines, you'll run the `domain.sh` script twice to start two separate
|
||||||
|
host controllers. The first will be the master host controller which will start a domain controller, an HTTP load balancer, and one
|
||||||
|
{{book.project.name}} authentication server instance. The second will be a slave host controller that only starts
|
||||||
|
up an authentication server instance.
|
||||||
|
|
||||||
|
===== Setup Slave Connection to Domain Controller
|
||||||
|
|
||||||
|
Before you can boot things up though, you have to configure the slave host controller so that it can talk securely to the domain
|
||||||
|
controller. If you do not do this, then the slave host will not be able to obtain the centralized configuration from the domain controller.
|
||||||
|
To set up a secure connection, you have to create a server admin user and a secret that
|
||||||
|
will be shared between the master and the slave. You do this by running the `.../bin/add-user.sh` script.
|
||||||
|
|
||||||
|
When you run the script select `Management User` and answer `yes` when it asks you if the new user is going to be used
|
||||||
|
for one AS process to connect to another. This will generate a secret that you'll need to cut and paste into the
|
||||||
|
_.../domain/configuration/host-slave.xml_ file.
|
||||||
|
|
||||||
|
.Add App Server Admin
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ add-user.sh
|
||||||
|
What type of user do you wish to add?
|
||||||
|
a) Management User (mgmt-users.properties)
|
||||||
|
b) Application User (application-users.properties)
|
||||||
|
(a): a
|
||||||
|
Enter the details of the new user to add.
|
||||||
|
Using realm 'ManagementRealm' as discovered from the existing property files.
|
||||||
|
Username : admin
|
||||||
|
Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.
|
||||||
|
- The password should not be one of the following restricted values {root, admin, administrator}
|
||||||
|
- The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)
|
||||||
|
- The password should be different from the username
|
||||||
|
Password :
|
||||||
|
Re-enter Password :
|
||||||
|
What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[ ]:
|
||||||
|
About to add user 'admin' for realm 'ManagementRealm'
|
||||||
|
Is this correct yes/no? yes
|
||||||
|
Added user 'admin' to file '/.../standalone/configuration/mgmt-users.properties'
|
||||||
|
Added user 'admin' to file '/.../domain/configuration/mgmt-users.properties'
|
||||||
|
Added user 'admin' with groups to file '/.../standalone/configuration/mgmt-groups.properties'
|
||||||
|
Added user 'admin' with groups to file '/.../domain/configuration/mgmt-groups.properties'
|
||||||
|
Is this new user going to be used for one AS process to connect to another AS process?
|
||||||
|
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
|
||||||
|
yes/no? yes
|
||||||
|
To represent the user add the following to the server-identities definition <secret value="bWdtdDEyMyE=" />
|
||||||
|
----
|
||||||
|
|
||||||
|
NOTE: The add-user.sh does not add user to {{book.project.name}} server but to the underlying JBoss Enterprise Application Platform. The credentials used and generated in the above script are only for example purpose. Please use the ones generated on your system.
|
||||||
|
|
||||||
|
Now cut and paste the secret value into the _.../domain/configuration/host-slave.xml_ file as follows:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<management>
|
||||||
|
<security-realms>
|
||||||
|
<security-realm name="ManagementRealm">
|
||||||
|
<server-identities>
|
||||||
|
<secret value="bWdtdDEyMyE="/>
|
||||||
|
</server-identities>
|
||||||
|
----
|
||||||
|
|
||||||
|
===== Run the Boot Scripts
|
||||||
|
|
||||||
|
Since we're simulating a two node cluster on one development machine, you'll run the boot script twice:
|
||||||
|
|
||||||
|
.Boot up master
|
||||||
|
[source,shell]
|
||||||
|
----
|
||||||
|
$ domain.sh --host-config=host-master.xml
|
||||||
|
----
|
||||||
|
|
||||||
|
.Boot up slave
|
||||||
|
[source,shell]
|
||||||
|
----
|
||||||
|
$ domain.sh --host-config=host-slave.xml
|
||||||
|
----
|
||||||
|
|
||||||
|
To try it out, open your browser and go to http://localhost:8080/auth
|
47
server_installation/topics/operating-mode/standalone-ha.adoc
Executable file
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
[[_standalone-ha-mode]]
|
||||||
|
|
||||||
|
=== Standalone Clustered Mode
|
||||||
|
|
||||||
|
Standalone clustered operation mode is for when you want to run {{book.project.name}} within a cluster. This mode
|
||||||
|
requires that you have a copy of the {{book.project.name}} distribution on each machine you want to run a server instance.
|
||||||
|
This mode can be very easy to deploy initially, but can become quite cumbersome. To make a configuration change
|
||||||
|
you'll have to modify each distribution on each machine. For a large cluster this can become time consuming and error prone.
|
||||||
|
|
||||||
|
==== Standalone Clustered Configuration
|
||||||
|
|
||||||
|
The distribution has a mostly pre-configured app server configuration file for running within a cluster. It has all the specific
|
||||||
|
infrastructure settings for networking, databases, caches, and discovery. This file resides
|
||||||
|
in _.../standalone/configuration/standalone-ha.xml_. There's a few things missing from this configuration.
|
||||||
|
You can't run {{book.project.name}} in a cluster without a configuring a shared database connection. You also need to
|
||||||
|
deploy some type of load balancer in front of the cluster. The <<fake/../../clustering.adoc#_clustering,clustering>> and
|
||||||
|
<<fake/../../database.adoc#_database,database>> sections of this guide walk you though these things.
|
||||||
|
|
||||||
|
.Standalone HA Config
|
||||||
|
image:../../{{book.images}}/standalone-ha-config-file.png[]
|
||||||
|
|
||||||
|
WARNING: Any changes you make to this file while the server is running will not take effect and may even be overwritten
|
||||||
|
by the server. Instead use the the command line scripting or the web console of {{book.appserver.name}}. See
|
||||||
|
the link:{{book.appserver.admindoc.link}}[{{_book.appserver.admindoc.name}}_] for more information.
|
||||||
|
|
||||||
|
==== Standalone Clustered Boot Script
|
||||||
|
|
||||||
|
You use the same boot scripts to start {{book.project.name}} as you do in standalone mode. The difference is that
|
||||||
|
you pass in an additional flag to point to the HA config file.
|
||||||
|
|
||||||
|
.Standalone Clustered Boot Scripts
|
||||||
|
image:../../{{book.images}}/standalone-boot-files.png[]
|
||||||
|
|
||||||
|
To boot the server:
|
||||||
|
|
||||||
|
.Linux/Unix
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ .../bin/standalone.sh --server-config=standalone-ha.xml
|
||||||
|
----
|
||||||
|
|
||||||
|
.Windows
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
> ...\bin\standalone.bat --server-config=standalone-ha.xml
|
||||||
|
----
|
44
server_installation/topics/operating-mode/standalone.adoc
Executable file
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
[[_standalone-mode]]
|
||||||
|
=== Standalone Mode
|
||||||
|
|
||||||
|
Standalone operating mode is only useful when you want to run one, and only one {{book.project.name}} server instance.
|
||||||
|
It is not usable for clustered deployments and all caches are non-distributed and local-only. It is not recommended that
|
||||||
|
you use standalone mode in production as you will have a single point of failure. If your standalone mode server goes down,
|
||||||
|
users will not be able to log in. This mode is really only useful to test drive and play with the features of {{book.project.name}}
|
||||||
|
|
||||||
|
==== Standalone Boot Script
|
||||||
|
|
||||||
|
When running the server in standalone mode, there is a specific script you need to run to boot the server depending on your
|
||||||
|
operating system. These scripts live in the _bin/_ directory of the server distribution.
|
||||||
|
|
||||||
|
.Standalone Boot Scripts
|
||||||
|
image:../../{{book.images}}/standalone-boot-files.png[]
|
||||||
|
|
||||||
|
To boot the server:
|
||||||
|
|
||||||
|
.Linux/Unix
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
$ .../bin/standalone.sh
|
||||||
|
----
|
||||||
|
|
||||||
|
.Windows
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
> ...\bin\standalone.bat
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Standalone Configuration
|
||||||
|
|
||||||
|
The bulk of this guide walks you through how to configure infrastructure level aspects of {{book.project.name}}. These
|
||||||
|
aspects are configured in a configuration file that is specific to the application server that {{book.project.name}} is a
|
||||||
|
derivative of. In the standalone operation mode, this file lives in _.../standalone/configuration/standalone.xml_. This file
|
||||||
|
is also used to configure non-infrastructure level things that are specific to {{book.project.name}} components.
|
||||||
|
|
||||||
|
.Standalone Config File
|
||||||
|
image:../../{{book.images}}/standalone-config-file.png[]
|
||||||
|
|
||||||
|
WARNING: Any changes you make to this file while the server is running will not take effect and may even be overwritten
|
||||||
|
by the server. Instead use the the command line scripting or the web console of {{book.appserver.name}}. See
|
||||||
|
the link:{{book.appserver.admindoc.link}}[_{{book.appserver.admindoc.name}}_] for more information.
|
15
server_installation/topics/overview.adoc
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
== Guide Overview
|
||||||
|
|
||||||
|
The purpose of this guide is to walk through the steps that need to be completed prior to booting up the
|
||||||
|
{{book.project.name}} server for the first time. If you just want to test drive {{book.project.name}}, it pretty much runs out of the box with its
|
||||||
|
own embedded and local-only database. For
|
||||||
|
actual deployments that are going to be run in production you'll need to decide how you want to manage server configuration
|
||||||
|
at runtime (standalone or domain mode), configure a shared database for {{book.project.name}} storage, set up encryption and HTTPS,
|
||||||
|
and finally set up {{book.project.name}} to run in a cluster. This guide walks through each and every aspect of any pre-boot
|
||||||
|
decisions and setup you must do prior to deploying the server.
|
||||||
|
|
||||||
|
One thing to particularly note is that {{book.project.name}} is derived from the {{book.appserver.name}} Application Server.
|
||||||
|
Many aspects of configuring {{book.project.name}} revolve around {{book.appserver.name}} configuration elements. Often
|
||||||
|
this guide will direct you to documentation outside of the manual if you want to dive into more detail.
|
||||||
|
|
8
server_installation/topics/overview/recommended-reading.adoc
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
=== Recommended Additional External Documentation
|
||||||
|
|
||||||
|
{{book.project.name}} is built on top of the {{book.appserver.name}} application server and it's sub-projects like Infinispan (for caching) and Hibernate (for persistence).
|
||||||
|
This guide only covers basics for infrastructure-level configuration. It is highly recommended that you peruse the documentation
|
||||||
|
for {{book.appserver.name}} and its sub projects. Here is the link to the documentation:
|
||||||
|
|
||||||
|
* link:{{book.appserver.admindoc.link}}[_{{book.appserver.admindoc.name}}_]
|
74
server_installation/topics/profiles.adoc
Executable file
|
@ -0,0 +1,74 @@
|
||||||
|
[[_app_server_cli]]
|
||||||
|
|
||||||
|
== Profiles
|
||||||
|
|
||||||
|
{% if book.community %}
|
||||||
|
{{book.project.name}} has a single profile, community, that enables all features by default, including features that
|
||||||
|
are considered less mature. It is however possible to disable individual features.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if book.product %}
|
||||||
|
{{book.project.name}} has two profiles, product and preview. The product profile is enabled by default, which disables
|
||||||
|
some tech preview features. To enable the features you can either switch to the preview profile or enable individual
|
||||||
|
features.
|
||||||
|
|
||||||
|
To enable the preview profile start the server with:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
bin/standalone.sh|bat -Dkeycloak.profile=preview
|
||||||
|
----
|
||||||
|
|
||||||
|
You can set this permanently by creating the file `standalone/configuration/profile.properties`
|
||||||
|
(or `domain/servers/server-one/configuration/profile.properties` for `server-one` in domain mode). Add the following to
|
||||||
|
the file:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
profile=preview
|
||||||
|
----
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
The features that can be enabled and disabled are:
|
||||||
|
|
||||||
|
* Authorization - authorization services
|
||||||
|
* Impersonation - ability for admins to impersonate users
|
||||||
|
* Script - write custom authenticators using JavaScript
|
||||||
|
|
||||||
|
{% if book.product %}
|
||||||
|
The product profile disables authorization and script.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
To disable a specific feature start the server with:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
bin/standalone.sh|bat -Dkeycloak.profile.feature.<feature name>=disabled
|
||||||
|
----
|
||||||
|
|
||||||
|
For example to disable Impersonation use `-Dkeycloak.profile.feature.impersonation=disabled`.
|
||||||
|
|
||||||
|
You can set this permanently in the `profile.properties` file by adding:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
feature.impersonation=disabled
|
||||||
|
----
|
||||||
|
|
||||||
|
{% if book.product %}
|
||||||
|
To enable a specific feature without enabling the full preview profile you can start the server with:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
bin/standalone.sh|bat -Dkeycloak.profile.feature.<feature name>=enabled`
|
||||||
|
----
|
||||||
|
|
||||||
|
For example to enable Authorization Services use `-Dkeycloak.profile.feature.authorization=enabled`.
|
||||||
|
|
||||||
|
You can set this permanently in the `profile.properties` file by adding:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
feature.authorization=enabled
|
||||||
|
----
|
||||||
|
{% endif %}
|
242
server_installation/topics/proxy.adoc
Executable file
|
@ -0,0 +1,242 @@
|
||||||
|
|
||||||
|
[[_proxy]]
|
||||||
|
== {{book.project.name}} Security Proxy
|
||||||
|
|
||||||
|
{{book.project.name}} has an HTTP(S) proxy that you can put in front of web applications and services where it is not possible to install the {{book.project.name}} 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.
|
||||||
|
|
||||||
|
=== Proxy Install and Run
|
||||||
|
|
||||||
|
Download the {{book.project.name}} proxy distribution from the {{book.project.name}} download pages and unzip it.
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
$ unzip keycloak-proxy-dist.zip
|
||||||
|
----
|
||||||
|
|
||||||
|
To run it you must have a proxy config file (which we'll discuss in a moment).
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
$ java -jar bin/launcher.jar [your-config.json]
|
||||||
|
----
|
||||||
|
|
||||||
|
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 `proxy.json`
|
||||||
|
|
||||||
|
=== Proxy Configuration
|
||||||
|
|
||||||
|
Here's an example configuration file.
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Basic Config
|
||||||
|
|
||||||
|
The basic configuration options for the server are as follows:
|
||||||
|
|
||||||
|
target-url::
|
||||||
|
The URL this server is proxying _REQUIRED._.
|
||||||
|
|
||||||
|
send-access-token::
|
||||||
|
Boolean flag.
|
||||||
|
If true, this will send the access token via the KEYCLOAK_ACCESS_TOKEN header to the proxied server. _OPTIONAL._.
|
||||||
|
Default is false.
|
||||||
|
|
||||||
|
bind-address::
|
||||||
|
DNS name or IP address to bind the proxy server's sockets to. _OPTIONAL._.
|
||||||
|
The default value is _localhost_
|
||||||
|
|
||||||
|
http-port::
|
||||||
|
Port to listen for HTTP requests.
|
||||||
|
If you do not specify this value, then the proxy will not listen for regular HTTP requests. _OPTIONAL._.
|
||||||
|
|
||||||
|
https-port::
|
||||||
|
Port to listen for HTTPS requests.
|
||||||
|
If you do not specify this value, then the proxy will not listen for HTTPS requests. _OPTIONAL._.
|
||||||
|
|
||||||
|
keystore::
|
||||||
|
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 `classpath:` it will look for this file in the classpath. _OPTIONAL._.
|
||||||
|
If you have enabled HTTPS, but have not defined a keystore, the proxy will auto-generate a self-signed certificate and use that.
|
||||||
|
|
||||||
|
buffer-size::
|
||||||
|
HTTP server socket buffer size.
|
||||||
|
Usually the default is good enough. _OPTIONAL._.
|
||||||
|
|
||||||
|
buffers-per-region::
|
||||||
|
HTTP server socket buffers per region.
|
||||||
|
Usually the default is good enough. _OPTIONAL._.
|
||||||
|
|
||||||
|
io-threads::
|
||||||
|
Number of threads to handle IO.
|
||||||
|
Usually default is good enough.
|
||||||
|
_OPTIONAL._.
|
||||||
|
The default is the number of available processors * 2.
|
||||||
|
|
||||||
|
worker-threads::
|
||||||
|
Number of threads to handle requests.
|
||||||
|
Usually the default is good enough. _OPTIONAL._.
|
||||||
|
The default is the number of available processors * 16.
|
||||||
|
|
||||||
|
=== Application Config
|
||||||
|
|
||||||
|
Next under the `applications` array attribute, you can define one or more applications per host you are proxying.
|
||||||
|
|
||||||
|
base-path::
|
||||||
|
The base context root for the application.
|
||||||
|
Must start with '/' _REQUIRED._.
|
||||||
|
|
||||||
|
error-page::
|
||||||
|
If the proxy has an error, it will display the target application's error page relative URL _OPTIONAL._.
|
||||||
|
This is a relative path to the base-path.
|
||||||
|
In the example above it would be `/customer-portal/error.html`.
|
||||||
|
|
||||||
|
adapter-config::
|
||||||
|
_REQUIRED._.
|
||||||
|
Same configuration as any other {{book.project.name}} adapter.
|
||||||
|
// See <<_adapter_config,Adapter Config>>
|
||||||
|
|
||||||
|
==== Constraint Config
|
||||||
|
|
||||||
|
Next under each application you can define one or more constraints in the `constraints` 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.
|
||||||
|
|
||||||
|
pattern::
|
||||||
|
URL pattern to match relative to the base-path of the application.
|
||||||
|
Must start with '/' _REQUIRED._
|
||||||
|
You may only have one wildcard and it must come at the end of the pattern.
|
||||||
|
|
||||||
|
* Valid: [x-]`/foo/bar/*` and [x-]`/foo/*.txt`
|
||||||
|
* Not valid: [x-]`/*/foo/*`.
|
||||||
|
|
||||||
|
roles-allowed::
|
||||||
|
Array of strings of roles allowed to access this url pattern. _OPTIONAL._.
|
||||||
|
|
||||||
|
methods::
|
||||||
|
Array of strings of HTTP methods that will exclusively match this pattern and HTTP request. _OPTIONAL._.
|
||||||
|
|
||||||
|
excluded-methods::
|
||||||
|
Array of strings of HTTP methods that will be ignored when match this pattern. _OPTIONAL._.
|
||||||
|
|
||||||
|
deny::
|
||||||
|
Deny all access to this URL pattern. _OPTIONAL._.
|
||||||
|
|
||||||
|
permit::
|
||||||
|
Permit all access without requiring authentication or a role mapping. _OPTIONAL._.
|
||||||
|
|
||||||
|
permit-and-inject::
|
||||||
|
Permit all access, but inject the headers, if user is already authenticated._OPTIONAL._.
|
||||||
|
|
||||||
|
authenticate::
|
||||||
|
Require authentication for this pattern, but no role mapping. _OPTIONAL._.
|
||||||
|
|
||||||
|
==== Header Names Config
|
||||||
|
|
||||||
|
Next under the list of applications you can override the defaults for the names of the header fields injected by the proxy (see {{book.project.name}} Identity Headers). This mapping is optional.
|
||||||
|
|
||||||
|
keycloak-subject::
|
||||||
|
e.g.
|
||||||
|
MYAPP_USER_ID
|
||||||
|
|
||||||
|
keycloak-username::
|
||||||
|
e.g.
|
||||||
|
MYAPP_USER_NAME
|
||||||
|
|
||||||
|
keycloak-email::
|
||||||
|
e.g.
|
||||||
|
MYAPP_USER_EMAIL
|
||||||
|
|
||||||
|
keycloak-name::
|
||||||
|
e.g.
|
||||||
|
MYAPP_USER_ID
|
||||||
|
|
||||||
|
keycloak-access-token::
|
||||||
|
e.g.
|
||||||
|
MYAPP_ACCESS_TOKEN
|
||||||
|
|
||||||
|
=== {{book.project.name}} Identity Headers
|
||||||
|
|
||||||
|
When forwarding requests to the proxied server, {{book.project.name}} Proxy will set some additional headers with values from the OIDC identity token it received for authentication.
|
||||||
|
|
||||||
|
KEYCLOAK_SUBJECT::
|
||||||
|
User id.
|
||||||
|
Corresponds to JWT `sub` and will be the user id {{book.project.name}} uses to store this user.
|
||||||
|
|
||||||
|
KEYCLOAK_USERNAME::
|
||||||
|
Username.
|
||||||
|
Corresponds to JWT `preferred_username`
|
||||||
|
|
||||||
|
KEYCLOAK_EMAIL::
|
||||||
|
Email address of user if set.
|
||||||
|
|
||||||
|
KEYCLOAK_NAME::
|
||||||
|
Full name of user if set.
|
||||||
|
|
||||||
|
KEYCLOAK_ACCESS_TOKEN::
|
||||||
|
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. Header field names can be configured using a map of `header-names` in configuration file:
|
||||||
|
+
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
|
||||||
|
{
|
||||||
|
"header-names" {
|
||||||
|
"keycloak-subject": "MY_SUBJECT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|