The Changes
We don't need to get into many details here, but the current version of Keycloak uses WildFly as the underlying container and the most recent version of WildFly drops support for the legacy security subsystem, which is being replaced fully by something called Elytron.
It is this that affects our SSL set up, as before we instructed the standalone.xml file be adjusted and a new security realm be added near the top of the file. That <security-realms> section no longer exists... Uh oh...
While on the subject of changes, more significant and disruptive development is underway with the Keycloak project (and has been for a while), with a shift from WildFly to Quarkus as the underlying technology. This promises to be "lighter, faster, easier, more scalable, more cloud native, and a bunch of other things." We'll try to keep on top of it and post updates on how this affects integrations with FileMaker Server.
The Configuration - CLI
This additional article is a substitute for the Configuring Keycloak To Use The SSL Certificate section of part 3 of our Keycloak series after which you should return to part 3 to continue with the section Renewing The SSL Certificate Automatically.
There's a couple of ways we can configure Keycloak to use our SSL certificate in Keycloak 16. The first is to use the WildFly Command Line Interface. To begin with we need to launch the CLI, so navigate to the folder where it resides with the command below:
cd /opt/keycloak/current/bin
Now let's get the CLI up and running:
sudo ./jboss-cli.sh
You'll notice it says we're disconnected, so let's address that with the obvious command:
connect
You should now see the following prompt, waiting for you to type your first command to get Keycloak configured to use your SSL certificate:
[standalone@localhost:9990 /]
Each time you run one of the commands below, you should get a result as shown here. If it shows anything other than the below, pause and try to figure out what's up:
{"outcome" => "success"}
So, let's execute our first command! Copy and paste the command below, being sure to update the placeholder keystore password for yours:
/subsystem=elytron/key-store=httpsKS:add(relative-to=jboss.server.config.dir,path=keycloak.jks,credential-reference={clear-text=KEYSTORE_PASSWORD},type=JKS)
That takes care of the keystore, so now run the below which creates a key manager (again be sure to replace the placeholder with your SSL password this time):
/subsystem=elytron/key-manager=httpsKM:add(key-store=httpsKS,credential-reference={clear-text=KEYCLOAK_SSL_PASSWORD})
This next command makes a ssl-context entry - note, TLSv1.3 could be used here:
/subsystem=elytron/server-ssl-context=httpsSSC:add(key-manager=httpsKM,protocols=["TLSv1.2"])
Finally, we adjust the https-listener entry to use the ssl-context we created above:
/subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=ssl-context,value=httpsSSC)
Now we perform a reload by executing this:
reload
That's it, we're done. Press Ctrl-Z to exit the CLI, and a reboot wouldn't hurt:
sudo shutdown -r now
The Configuration - standalone.xml
Before we move on to checking that our SSL certificate is working properly, let's take a look at what changes the above commands had on our standalone.xml file. If you're more comfortable editing the xml directly rather than having the commands do it for you, then this section is for you also.
The first chunk of xml we come across that has been updated is the <tls> section. Originally, the entire section looked like this:
<tls> <key-stores> <key-store name="applicationKS"> <credential-reference clear-text="password"></credential-reference> <implementation type="JKS"></implementation> <file path="application.keystore" relative-to="jboss.server.config.dir"></file> </key-store> </key-stores> <key-managers> <key-manager name="applicationKM" key-store="applicationKS" generate-self-signed-certificate-host="localhost"> <credential-reference clear-text="password"></credential-reference> </key-manager> </key-managers> <server-ssl-contexts> <server-ssl-context name="applicationSSC" key-manager="applicationKM"></server-ssl-context> </server-ssl-contexts> </tls>
After we executed our first command, we added a keystore reference - note the second keystore entry named httpsKS:
<key-stores> <key-store name="applicationKS"> <credential-reference clear-text="password"></credential-reference> <implementation type="JKS"></implementation> <file path="application.keystore" relative-to="jboss.server.config.dir"></file> </key-store> <key-store name="httpsKS"> <credential-reference clear-text="KEYSTORE_PASSWORD"></credential-reference> <implementation type="JKS"></implementation> <file path="keycloak.jks" relative-to="jboss.server.config.dir"></file> </key-store> </key-stores>
Our second command added a new key manager entry:
<key-managers> <key-manager name="applicationKM" key-store="applicationKS" generate-self-signed-certificate-host="localhost"> <credential-reference clear-text="password"></credential-reference> </key-manager> <key-manager name="httpsKM" key-store="httpsKS"> <credential-reference clear-text="KEYCLOAK_SSL_PASSWORD"></credential-reference> </key-manager> </key-managers>
And finally in this section, we added a new ssl-context:
<server-ssl-contexts> <server-ssl-context name="applicationSSC" key-manager="applicationKM"></server-ssl-context> <server-ssl-context name="httpsSSC" protocols="TLSv1.2" key-manager="httpsKM"></server-ssl-context> </server-ssl-contexts>
Our last command adjusted a different section of the xml, which originally looked like this:
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="$<span data-mce-code=" shortcode="" data-mce-type="code"><span>{wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}</span>"> <buffer-cache name="default"></buffer-cache> <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"></http-listener> <https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true"></https-listener> <host name="default-host" alias="localhost"> <location name="/" handler="welcome-content"> <http-invoker http-authentication-factory="application-http-authentication"></http-invoker> </location> </host> </server> <servlet-container name="default"> <jsp-config></jsp-config> <websockets></websockets> </servlet-container> <handlers> <file name="welcome-content" path="$<span data-mce-code=" shortcode="" data-mce-type="code"><span>{jboss.home.dir}</span>/welcome-content"/> </file> </handlers> <application-security-domains> <application-security-domain name="other" security-domain="ApplicationDomain"></application-security-domain> </application-security-domains> </subsystem>
We changed the https-listener value, just a few rows down, and now that section looks like this:
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="$<span data-mce-code=" shortcode="" data-mce-type="code"><span>{wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}</span>"> <buffer-cache name="default"></buffer-cache> <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"></http-listener> <https-listener name="https" socket-binding="https" ssl-context="httpsSSC" enable-http2="true"></https-listener> <host name="default-host" alias="localhost"> <location name="/" handler="welcome-content"> <http-invoker http-authentication-factory="application-http-authentication"></http-invoker> </location> </host> </server> <servlet-container name="default"> <jsp-config></jsp-config> <websockets></websockets> </servlet-container> <handlers> <file name="welcome-content" path="$<span data-mce-code=" shortcode="" data-mce-type="code"><span>{jboss.home.dir}</span>/welcome-content"/> </file> </handlers> <application-security-domains> <application-security-domain name="other" security-domain="ApplicationDomain"></application-security-domain> </application-security-domains> </subsystem>
The Configuration - Testing
Once the machine has rebooted, give it a couple minutes to get all services up and running and then try going here in a browser:
https://DOMAIN_SUBDOMAIN:8443/auth/
We're crossing our fingers for you and hoping that you see the Welcome to Keycloak page along with a lock icon to indicate the connection is encrypted. If not, then pour over the details above making sure that you got everything right as the smallest thing can break the entire application.
If that works fine, then awesome, and let's check that the port forwarding we set up earlier works:
https://DOMAIN_SUBDOMAIN/auth/
You should land at the same place but note that this time we omitted the port number in the web address. It's important that this works, because as of FileMaker Server 19.4.1, you can not use a port number in the Keycloak web address - hopefully this will change in the future.
If you've got this far and all is looking good, then head back to part 3 of our Keycloak series and continue with the section Renewing The SSL Certificate Automatically.
Summary
The technology we rely on to achieve our goals will always continue to evolve, mostly for the better. We as FileMaker developers need to embrace that change and keep up - it happens with the primary software we use to solve business problems, and it happens with the software we augment FileMaker with. The scripts above actually simplify the configuration of the SSL certificate somewhat, so while we needed to figure it out, it's a welcome change. If you need help setting up Keycloak or another OAuth provider, don't hesitate to get in touch.
And if you need general help with your FileMaker app, or want to save money on your licensing of Claris products, contact us and we'll be glad to assist.