1. Install Keycloak¶
We will install and launch Keycloak server behind Apache.
Login to the host where you will install Keycloak. In this tutorial, we are installing Keycloak on the same host as OnDemand, which is webdev07.hpc.osc.edu.
Warning
In production we recommend installing Keycloak on a separate host from OnDemand.
1.1. Initial Installation Steps¶
Download and unpack Keycloak 9.0.0 (from https://www.keycloak.org/downloads.html)
cd /opt sudo wget https://downloads.jboss.org/keycloak/9.0.0/keycloak-9.0.0.tar.gz sudo tar xzf keycloak-9.0.0.tar.gz
Add keycloak user and change ownership of files
sudo groupadd -r keycloak sudo useradd -m -d /var/lib/keycloak -s /sbin/nologin -r -g keycloak keycloak
If
-m
doesn’t work, do this:sudo install -d -o keycloak -g keycloak /var/lib/keycloak
This makes a home directory, which is needed when running API calls as keycloak user. Finally we set proper permissions:
sudo chown keycloak: -R keycloak-9.0.0
Restrict access to keycloak-9.0.0/standalone, which will contain sensitive data for the Keycloak server
cd keycloak-9.0.0 sudo -u keycloak chmod 700 standalone
Install JDK 1.8.0
sudo yum install java-1.8.0-openjdk-devel
Added ‘admin’ to ‘/opt/keycloak-9.0.0/standalone/configuration/keycloak-add-user.json’, (re)start server to load user.
If you are not already there:
cd /opt/keycloak-9.0.0
Generate a password to use for the admin user:
openssl rand -hex 20 # generate a password to use for admin user sudo -u keycloak ./bin/add-user-keycloak.sh --user admin --password KEYCLOAKPASS --realm master
Replace KEYCLOAKPASS with a good password and save password for later use
Modify
standalone/configuration/standalone.xml
to enable proxying to Keycloak:Simplest is to run these three commands:
sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)' sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443)' sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket,value=proxy-https)'
Or you can use a config.cli file that contains these commands. We have provided an example file to make use of in this gist, with blocks commented out so you can wget the file, edit as appropriate, and run via:
sudo -u keycloak ./bin/jboss-cli.sh --file=config.cli
Where the config.cli looks like:
embed-server /subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true) /subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket,value=proxy-https) /socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443) # uncomment if using truststore, replacing erb tags <%= %> with correct values # truststore needed if ldap servers are not using trusted certificates (i.e. self signed certificates) # #if (outcome != success) of /subsystem=keycloak-server/spi=truststore:read-resource #/subsystem=keycloak-server/spi=truststore/:add #/subsystem=keycloak-server/spi=truststore/provider=file/:add(enabled=true) #end-if #/subsystem=keycloak-server/spi=truststore/provider=file/:map-put(name=properties,key=file,value=<%= scope['keycloak::install_base'] %>/standalone/configuration/truststore.jks) #/subsystem=keycloak-server/spi=truststore/provider=file/:map-put(name=properties,key=password,value=<%= scope['keycloak::truststore_password'] %>) #/subsystem=keycloak-server/spi=truststore/provider=file/:map-put(name=properties,key=hostname-verification-policy,value=<%= scope['keycloak::truststore_hostname_verification_policy'] %>) #/subsystem=keycloak-server/spi=truststore/provider=file/:map-put(name=properties,key=disabled,value=false) # uncomment if doing theme development, so you don't need to restart Keycloak # with every theme modification # #/subsystem=keycloak-server/theme=defaults/:write-attribute(name=staticMaxAge, value=-1) #/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes, value=false) #/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates, value=false)
1.2. Start Keycloak Server¶
Create keycloak.service to start and stop the server:
sudo cat > /etc/systemd/system/keycloak.service <<EOF [Unit] Description=Jboss Application Server After=network.target [Service] Type=idle User=keycloak Group=keycloak ExecStart=/opt/keycloak-9.0.0/bin/standalone.sh -b 0.0.0.0 TimeoutStartSec=600 TimeoutStopSec=600 [Install] WantedBy=multi-user.target EOF
Then start keycloak:
sudo systemctl daemon-reload sudo systemctl start keycloak
It may take a little time to load; verify it has loaded:
sudo systemctl status keycloak # keycloak.service - Jboss Application Server # Loaded: loaded (/etc/systemd/system/keycloak.service; disabled; vendor preset: disabled) # Active: active (running) since Mon 2017-09-25 16:19:47 EDT; 2s ago # ... # Sep 25 16:19:49 webdev07.hpc.osc.edu standalone.sh[111998]: 16:19:49,644 INFO [#org.wildfly.extension.undertow] (MSC service thread ...0:8080) # Hint: Some lines were ellipsized, use -l to show in full.
1.3. Place Apache in front of Keycloak¶
Define apache config to proxy keycloak requests
Note
This is the only step in the tutorial that differs significantly based on whether you install Keycloak on a separate host from OnDemand or on the same host. See below for example differences.
We will stick Apache in front of Keycloak. In this tutorial Keycloak is installed on the same node as OnDemand, and we use the same Apache instance to serve both OnDemand and Keycloak with the same host, so we can reuse the same SSL certificates. You may want to run Keycloak on a separate host, however.
Add
/opt/rh/httpd24/root/etc/httpd/conf.d/ood-keycloak.conf
, making changes for the appropriate SSL certificate locations. Notice we are proxyinghttps://ondemand-idpdev.hpc.osc.edu
tohttp://localhost:8080
which is the default port the Keycloak webserver runs as.<VirtualHost *:443> ServerName ondemand-idpdev.hpc.osc.edu ErrorLog "logs/keycloak_error_ssl.log" CustomLog "logs/keycloak_access_ssl.log" combined SSLEngine On SSLCertificateFile "/etc/pki/tls/certs/webdev07.hpc.osc.edu.crt" SSLCertificateKeyFile "/etc/pki/tls/private/webdev07.hpc.osc.edu.key" SSLCertificateChainFile "/etc/pki/tls/certs/webdev07.hpc.osc.edu-interm.crt" # Proxy rules ProxyRequests Off ProxyPreserveHost On ProxyPass / http://localhost:8080/ ProxyPassReverse / http://localhost:8080/ ## Request header rules ## as per http://httpd.apache.org/docs/2.2/mod/mod_headers.html#requestheader RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443" </VirtualHost>
Note
We can use the same host because Keycloak properly scopes all cookies it sets to the realm. For example, if I have a realm called “ondemand”, then the Keycloak login page will be at
https://ondemand-idpdev.hpc.osc.edu/auth/realms/ondemand/protocol/openid-connect/auth
and cookies set during authentication will be set with the path/auth/realms/ondemand
, includingKEYCLOAK_SESSION
,KEYCLOAK_STATE_CHECKER
,KEYCLOAK_IDENTITY
, andKC_RESTART
.Now you should be able to access Keycloak:
https://ondemand-idpdev.hpc.osc.edu
1.4. Differences if installing Keycloak on separate host¶
When installing Keycloak on a separate host, the difference between this tutorial would be:
- throughout the rest of the tutorial replace
https://ondemand-idpdev.hpc.osc.edu
with the keycloak host - possibly use Apache 2.4 default distribution instead of software collections,
meaning that configuration would be at /etc/httpd/conf.d/ instead of
/opt/rh/httpd24/root/etc/httpd/conf.d/ and starting the
service is likely
sudo systemctl start httpd
instead ofsudo systemctl start httpd24-httpd
For example, if Keycloak were installed on a separate host idp.hpc.edu then the Apache config might look like:
<VirtualHost *:443>
ServerName idp.hpc.edu
ErrorLog "/var/log/httpd/idp.hpc.edu_error_ssl.log"
CustomLog "/var/log/httpd/idp.hpc.edu_access_ssl.log" combined
## SSL directives
SSLEngine on
SSLCertificateFile "/etc/pki/tls/certs/idp.hpc.edu.crt"
SSLCertificateKeyFile "/etc/pki/tls/private/idp.hpc.edu.key"
SSLCertificateChainFile "/etc/pki/tls/certs/idp.hpc.edu-interm.crt"
SSLCACertificatePath "/etc/pki/tls/certs"
# Proxy rules
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
## Request header rules
## as per http://httpd.apache.org/docs/2.2/mod/mod_headers.html#requestheader
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>