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 - -mdoesn’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.xmlto 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 proxying- https://ondemand-idpdev.hpc.osc.eduto- http://localhost:8080which 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/authand cookies set during authentication will be set with the path- /auth/realms/ondemand, including- KEYCLOAK_SESSION,- KEYCLOAK_STATE_CHECKER,- KEYCLOAK_IDENTITY, and- KC_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.eduwith 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 httpdinstead 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>