Securing WildFly Apps with SAML on OpenShift
- Prerequisites
- Example Application
- Log Into the OpenShift Cluster
- Start Keycloak
- Configure Keycloak
- Download the SAML Keys
- Download and Edit the Keycloak Adapter Configuration File
- Add Helm Configuration
- Deploy the Example Application to WildFly on OpenShift
- Get the Application URL
- Finish Configuring Keycloak
- Access the Application
- What’s next?
- References
You can secure your WildFly applications deployed on OpenShift with Security Assertion Markup Language (SAML). By using SAML to secure applications, you delegate authentication to SAML identity providers (IdPs). This guide shows how to secure an example application deployed to WildFly on OpenShift with SAML using Keycloak as the SAML IdP.
Prerequisites
To complete this guide, you need:
-
Roughly 15 minutes
-
JDK 11+ installed with
JAVA_HOME
configured appropriately -
Apache Maven 3.9+
-
Access to an OpenShift cluster (try the Red Hat Developer Sandbox for free)
Example Application
We will use a simple web application in this guide that consists of a single servlet. We will secure this servlet using SAML.
We will use the example in the simple-webapp-saml directory in the elytron-examples
repo.
To obtain this example, clone the elytron-examples
repository to your local machine:
git clone git@github.com:wildfly-security-incubator/elytron-examples.git
Log Into the OpenShift Cluster
Before we can deploy our application, we need to log in to an OpenShift cluster. You can log in via the OpenShift CLI:
oc login -u myUserName
Alternatively, you can log in using an API token:
oc login --token=myToken --server=myServerUrl
You can request the token via the Copy Login Command
link in the OpenShift web console.
If you don’t already have a project created, you can create one using:
oc new-project myProjectName
Start Keycloak
We will be using Keycloak as our SAML identity provider.
To start a Keycloak server in your project on OpenShift, use the following command:
oc process -f https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/latest/openshift/keycloak.yaml \
-p KEYCLOAK_ADMIN=admin \// (1)
-p KEYCLOAK_ADMIN_PASSWORD=admin \// (2)
-p NAMESPACE=<PROJECT_NAME> \// (3)
| oc create -f -
-
Replace
admin
with the user name you would like to use when accessing the Keycloak Administration Console. -
Replace
admin
with the password you would like to use when accessing the Keycloak Administration Console. -
Replace
<PROJECT_NAME>
with your project name.
After running the above command, you should see the following output:
service/keycloak created
route.route.openshift.io/keycloak created
Warning: apps.openshift.io/v1 DeploymentConfig is deprecated in v4.14+, unavailable in v4.10000+
deploymentconfig.apps.openshift.io/keycloak created.
It will take a few minutes for OpenShift to provision the Keycloak pod and its related resources.
You can use the OpenShift CLI or the OpenShift web console, depending on your preference, to check if your Keycloak server has been provisioned.
OpenShift CLI
To make sure your Keycloak server has been provisioned using the OpenShift CLI, run:
oc get pods
After a little while, check for a message similar to the following message that indicates the pod is ready:
NAME READY STATUS RESTARTS AGE
keycloak-1-deploy 0/1 Completed 0 1h
keycloak-1-l9kdx 1/1 Running 0 1h
Once the Keycloak server has been provisioned, use the following command to find the URL for your Keycloak instance’s Admin Console:
KEYCLOAK_URL=https://$(oc get route keycloak --template='{{ .spec.host }}') &&
echo "" &&
echo "Keycloak Admin Console: $KEYCLOAK_URL/admin" &&
echo ""
OpenShift Web Console
To make sure your Keycloak server has been provisioned using the OpenShift web console,
navigate to the Topology
view in the Developer
perspective. You can click on your keycloak
app
to check its status. Once it is running, you can click on Open URL
and then access Keycloak’s Administration Console
.
Configure Keycloak
-
Log into the
Keycloak Admin Console
. -
Create a new realm called
myrealm
. For more information, see the Keycloak documentation on how to create a realm. -
Add a role called
user
. This role will be required to access our simple web application. For more information, see the Keycloak documentation on how to create a role. -
Add a new user named
alice
. Set anemail
address for this new user, we’ll usealice@example.org
. For more information, see the Keycloak documentation on how to create a user. -
Once the new user has been created, set a password for this new user from the
Credentials
tab. -
From the
Role Mapping
tab, assignalice
theuser
role. For more information, see the Keycloak documentation on how to assign a role to a user. -
Create a new client as follows:
-
General Settings
:-
Client type (or Client Protocol, depending on your Keycloak version):
SAML
-
Client ID:
simple-webapp-saml
-
-
Login settings
: Leave the fields blank for now.
For more information, see the Keycloak documentation on how to Create SAML clients.
-
-
Click
Save
to save the client. -
Once the new client has been created, in the
Settings
tab, scroll down to theSAML capabilities
section and set theName ID format
toemail
. When accessing our servlet later on, we will see that this results inHttpServletRequest.getUserPrincipal().getName()
returning the logged in user’s email address. -
Then set
Force name ID format
toOn
. Then click onSave
.
Download the SAML Keys
-
From your
simple-webapp-saml
client in the Keycloak Admin Console, click on theKeys
tab. -
Click on the
Export
button in theSigning keys config
to export the SAML keys to a keystore. -
Set the Key alias to
simple-webapp-saml
, the Key password topassword
, the Realm certificate alias tomyrealm
, and the Store password topassword
.Take note of the aliases and passwords that you specify here since these will be used when updating the
keycloak-saml.xml
file. -
Click on
Export
to download the correspondingkeystore.jks
file. -
Create an OpenShift secret using this keystore by running the following command:
oc create secret generic simple-webapp-saml-secret --from-file=/PATH/TO/keystore.jks
Download and Edit the Keycloak Adapter Configuration File
-
From your
simple-webapp-saml
client in the Keycloak Admin Console, click on theAction
dropdown in the top right corner and selectDownload Adapter Config
. -
For the
Format option
, select theKeycloak SAML Adapter keycloak-saml.xml
, and download the file and place it in the example application’sWEB-INF
directory, i.e., place thekeycloak-saml.xml
file in/PATH/TO/ELYTRON/EXAMPLES/simple-webapp-saml/src/main/webapp/WEB-INF
. -
Update the
keycloak-saml.xml
file as follows:-
Set the SP entityID to
"simple-webapp-saml"
-
Set the SP logoutPage to
"/simple-webapp-saml"
-
Replace the SP Keys configuration with the following configuration, being sure to use the aliases and passwords you specified when exporting the SAML keys to the
keystore.jks
file:<Keys> <Key signing="true"> <KeyStore password="password" file="/etc/keycloak-saml-secret-volume/keystore.jks"> <PrivateKey alias="simple-webapp-saml" password="password"/> <Certificate alias="myrealm"/> </KeyStore> </Key> </Keys>
-
Push this new file to the
simple-webapp-saml
directory in yourelytron-examples
fork, making sure to push the changes to your fork’s default branch.cd /PATH/TO/ELYTRON/EXAMPLES/simple-webapp-saml git add src/main/webapp/WEB-INF/keycloak-saml.xml git commit -m "Added Keycloak adapter deployment descriptor file" git push origin main
-
Add Helm Configuration
Let’s switch to the charts
directory in our simple-webapp-saml
example:
cd /PATH/TO/ELYTRON/EXAMPLES/simple-webapp-saml/charts
Notice there’s a helm.yaml
file in this directory with the following content:
build:
uri: https://github.com/YOUR_GITHUB_USERNAME/elytron-examples (1)
contextDir: simple-webapp-saml
deploy:
volumes:
- name: saml-keystore-volume
secret:
secretName: simple-webapp-saml-secret
volumeMounts:
- name: saml-keystore-volume
mountPath: /etc/keycloak-saml-secret-volume
readOnly: true
-
Replace
YOUR_GITHUB_USERNAME
in the build uri with your own GitHub username.
The helm.yaml
file specifies the Git repository that contains our application’s source code.
Because we have modified the application’s source code by adding a keycloak-saml.xml
file, you need
to set the build uri in the helm.yaml
file to point to your own fork.
Notice that our helm.yaml
file also refers to the OpenShift secret, simple-webapp-saml-secret
we
created earlier. This will be used to mount the keystore.jks
file on our WildFly server pod.
Deploy the Example Application to WildFly on OpenShift
We can deploy our example application to WildFly on OpenShift using the WildFly Helm Chart:
helm install saml-app -f /PATH/TO/ELYTRON/EXAMPLES/simple-webapp-saml/charts/helm.yaml wildfly/wildfly
Notice that this command specifies the file we updated, helm.yaml
, that contains the values
needed to build and deploy our application.
The application will now begin to build. This will take a couple of minutes.
The build can be observed using:
oc get build -w
Once complete, you can follow the deployment of the application using:
oc get deployment oidc-app -w
Alternatively, you can check status directly from the OpenShift web console.
Behind the Scenes
While our application is building, let’s take a closer look at our application’s pom.xml file.
Notice that it contains the following wildfly-maven-plugin
configuration:
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.wildfly.plugin}</version>
<configuration>
<feature-packs>
<feature-pack>
<location>org.wildfly:wildfly-galleon-pack:${version.wildfly}</location>
</feature-pack>
<feature-pack>
<location>org.wildfly.cloud:wildfly-cloud-galleon-pack:${version.wildfly.cloud.galleon.pack}</location>
</feature-pack>
<feature-pack>
<location>org.keycloak:keycloak-saml-adapter-galleon-pack:${version.keycloak}</location>
</feature-pack>
</feature-packs>
<layers>
<layer>cloud-server</layer>
<layer>keycloak-client-saml</layer>
</layers>
</configuration>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
This configuration is used to provision a WildFly server with the specified layers and with our application deployed.
The keycloak-client-saml
layer automatically adds the Keycloak SAML adapter to our WildFly installation.
Get the Application URL
Once the WildFly server has been provisioned, use the following command to find the URL for your example application:
SIMPLE_WEBAPP_SAML_URL=https://$(oc get route saml-app --template='{{ .spec.host }}') &&
echo "" &&
echo "Application URL: $SIMPLE_WEBAPP_SAML_URL/simple-webapp-saml" &&
echo "Master SAML Processing URL: $SIMPLE_WEBAPP_SAML_URL/simple-webapp-saml/saml" &&
echo ""
We’ll make use of these URLs in the next two sections.
Finish Configuring Keycloak
From your simple-webapp-saml
client in the Keycloak Administration Console,
In the client settings, set Master SAML Processing URL
to the Master SAML Processing URL
that was output
in the previous section and then click Save
.
Access the Application
From your browser, navigate to the Application URL
.
Click on Access Secured Servlet
.
You will be redirected to Keycloak to log in.
Log in using the alice
user we created earlier.
Upon successful authentication, you will be redirected back to the example application.
The example application simply outputs the email address associated with our logged in user.
You should see the following output:
Current Principal 'alice@example.org'
This indicates that we have successfully logged into our application!
What’s next?
This guide has shown how to secure an application deployed to WildFly on OpenShift with SAML. For additional information, feel free to check out the resources linked below.