-
Notifications
You must be signed in to change notification settings - Fork 280
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1944 from fjuma/develop
Add a blog post that explains how to secure an application deployed to WildFly on OpenShift with SAML
- Loading branch information
Showing
2 changed files
with
390 additions
and
0 deletions.
There are no files selected for viewing
382 changes: 382 additions & 0 deletions
382
_posts/2023-09-06-securing-wildfly-apps-saml-openshift.adoc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,382 @@ | ||
--- | ||
layout: post | ||
title: 'Securing WildFly Apps with SAML on OpenShift' | ||
date: 2023-09-06 | ||
tags: saml openshift keycloak adapter galleon-pack | ||
synopsis: Learn how to secure applications deployed to WildFly on OpenShift with SAML. | ||
author: fjuma | ||
--- | ||
|
||
:toc: macro | ||
:toc-title: | ||
|
||
Starting with WildFly 29, you can use Galleon to add https://www.keycloak.org/docs/latest/securing_apps/#using-saml-to-secure-applications-and-services[Keycloak's SAML adapter] to your WildFly | ||
installation using the new Keycloak SAML Adapter feature pack. In this guide, we'll show how | ||
to secure an application deployed to WildFly on OpenShift with SAML. | ||
|
||
toc::[] | ||
|
||
== Prerequisites | ||
|
||
To follow along with this guide, you will need: | ||
|
||
* Roughly 15 minutes | ||
* An IDE | ||
* Access to an OpenShift cluster (try the https://developers.redhat.com/developer-sandbox[Red Hat Developer Sandbox] for free) | ||
* https://docs.openshift.com/container-platform/4.13/cli_reference/openshift_cli/getting-started-cli.html[OpenShift CLI] | ||
* https://docs.wildfly.org/29/Getting_Started_on_OpenShift.html#helm-charts[WildFly Helm Chart] | ||
|
||
== Example Application | ||
|
||
We will be using a simple web application in this guide that consists of a single https://github.com/wildfly-security/elytron-examples/blob/main/simple-webapp-saml/src/main/java/org/wildfly/security/examples/SecuredServlet.java[servlet]. We will secure | ||
this servlet using SAML. | ||
|
||
You'll need to fork and then clone this Git repository: https://github.com/wildfly-security-incubator/elytron-examples.git | ||
|
||
We will be using the example in the https://github.com/wildfly-security-incubator/elytron-examples/tree/main/simple-webapp-saml[simple-webapp-saml] directory in this repo. | ||
|
||
== Log Into the OpenShift Cluster | ||
|
||
Before we can deploy our application, we need to log into an OpenShift cluster. You can log in via the https://docs.openshift.com/container-platform/4.13/cli_reference/openshift_cli/getting-started-cli.html[OpenShift CLI]: | ||
|
||
[source] | ||
---- | ||
oc login -u myUserName | ||
---- | ||
|
||
Alternatively, you can log in using an API token: | ||
|
||
[source] | ||
---- | ||
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: | ||
|
||
[source] | ||
---- | ||
oc new-project myProjectName | ||
---- | ||
|
||
== Start Keycloak | ||
|
||
We will be using Keycloak for our SAML identity provider. | ||
|
||
To start a Keycloak server in your project on OpenShift, use the following command: | ||
|
||
[source] | ||
---- | ||
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=myNameSpace \ // <3> | ||
| oc create -f - | ||
---- | ||
<1> Replace `admin` with the user name you would like to use when accessing the Keycloak Administration Console. | ||
<2> Replace `admin` with the password you would like to use when accessing the Keycloak Administration Console. | ||
<3> Replace `myNameSpace` with your project name. | ||
|
||
After running the above command, you should see the following output: | ||
|
||
[source] | ||
---- | ||
service/keycloak created | ||
route.route.openshift.io/keycloak created | ||
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: | ||
|
||
[source] | ||
---- | ||
oc get pods | ||
---- | ||
|
||
After a little while, check for a message similar to the following message that indicates the pod is ready: | ||
|
||
[source] | ||
---- | ||
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: | ||
|
||
[source] | ||
---- | ||
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 using the username and password you specified earlier. | ||
|
||
. Create a new realm called *myrealm*. For more information, see the Keycloak documentation on how to https://www.keycloak.org/getting-started/getting-started-openshift#_create_a_realm[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 https://www.keycloak.org/docs/latest/server_admin/index.html#assigning-permissions-using-roles-and-groups[create a role]. | ||
|
||
. Add a new user named *alice*. Set an *email* address for this new user, we'll use *[email protected]*. For more information, see the Keycloak documentation on how to https://www.keycloak.org/getting-started/getting-started-openshift#_create_a_user[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, assign *alice* the *user* role. For more information, see the Keycloak documentation on how to https://www.keycloak.org/docs/latest/server_admin/index.html#proc-assigning-role-mappings_server_administration_guide[assign a role] to a user. | ||
|
||
. Create a new client as follows: | ||
** *Client type* (or *Client Protocol*, depending on your Keycloak version): *saml* | ||
** *Client ID*: *simple-webapp-saml* | ||
+ | ||
For more information, see the Keycloak documentation on how to https://www.keycloak.org/docs/latest/server_admin/index.html#_client-saml-configuration[create a SAML client]. | ||
|
||
. Once the new client has been created, in the *Settings* tab, scroll down to the *SAML capabilities* section and | ||
set the *Name ID format* to *email*. When accessing | ||
our servlet later on, we will see that this results in `HttpServletRequest.getUserPrincipal().getName()` returning | ||
the logged in user's email address. | ||
|
||
. Then set *Force name ID format* to *On*. Then click on *Save*. | ||
|
||
== Download the SAML Keys | ||
|
||
. From your *simple-webapp-saml* client in the Keycloak Admin Console, click on the *Keys* tab. | ||
|
||
. Click on the *Export* button in the *Signing keys config* to export the SAML keys to a keystore. | ||
|
||
. Set the *Key alias* to *simple-webapp-saml*, the *Key password* to *password*, | ||
the *Realm certificate alias* to *myrealm*, and the *Store password* to *password*. | ||
+ | ||
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 corresponding `keystore.jks` file. | ||
|
||
. Create an OpenShift secret using this keystore by running the following command: | ||
+ | ||
[source] | ||
---- | ||
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 the *Action* dropdown in the top right corner | ||
and select *Download Adapter Config*. | ||
|
||
. For the *Format option*, select the *Keycloak SAML Adapter keycloak-saml.xml*, and download the file and place it in the example | ||
application's `WEB-INF` directory, i.e., place the `keycloak-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: | ||
+ | ||
[source] | ||
---- | ||
<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 your `elytron-examples` fork, making | ||
sure to push the changes to your fork's default branch. | ||
+ | ||
[source] | ||
---- | ||
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: | ||
|
||
[source] | ||
---- | ||
cd /PATH/TO/ELYTRON/EXAMPLES/simple-webapp-saml/charts | ||
---- | ||
|
||
Notice there's a `helm.yaml` file in this directory with the following content: | ||
|
||
[source] | ||
---- | ||
build: | ||
uri: https://github.com/YOUR_GITHUB_USERNAME/elytron-examples | ||
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: | ||
|
||
[source] | ||
---- | ||
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: | ||
|
||
[source] | ||
---- | ||
oc get build -w | ||
---- | ||
|
||
Once complete, you can follow the deployment of the application using: | ||
|
||
[source] | ||
---- | ||
oc get deployment saml-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 https://github.com/wildfly-security/elytron-examples/blob/main/simple-webapp-saml/pom.xml[pom.xml] file. | ||
Notice that it contains the following *wildfly-maven-plugin* configuration: | ||
|
||
[source] | ||
---- | ||
<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: | ||
|
||
[source] | ||
---- | ||
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 '[email protected]' | ||
``` | ||
|
||
This indicates that we have successfully logged into our application! | ||
|
||
== Summary | ||
|
||
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. | ||
|
||
== Resources | ||
|
||
* https://docs.wildfly.org/29/Getting_Started_on_OpenShift.html[Getting Started with WildFly on OpenShift] | ||
* https://docs.openshift.com/container-platform/4.13/cli_reference/openshift_cli/getting-started-cli.html[OpenShift CLI] | ||
* https://docs.wildfly.org/29/Getting_Started_on_OpenShift.html#helm-charts[WildFly Helm Chart] | ||
* https://www.keycloak.org/getting-started/getting-started-openshift[Getting started with Keycloak on OpenShift] | ||
* https://www.keycloak.org/docs/latest/server_admin/index.html[Keycloak Server Administration Guide] | ||
* https://www.keycloak.org/docs/latest/securing_apps/#using-saml-to-secure-applications-and-services[Using SAML to secure applications and services] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters