Apache CXF
Fediz originated as a way of securing web applications using Single Sign-On via the
WS-Federation Passive Requestor Profile. Plugins were written to support the most popular web application containers, such as Apache Tomcat, Jetty, Spring, Websphere, etc. Fediz then shipped an
IdP which could be used to perform authentication using the container plugins. For the 1.3.0 release, support was
added to the IdP to also support the SAML SSO protocol. From the next 1.4.4 release, the Tomcat 8 plugin can authenticate to a SAML SSO IdP, instead of using WS-Federation, with a few simple configuration changes. This makes it very easy to upgrade your Fediz-secured containers to use SAML SSO instead of WS-Federation.
In this article, we will secure the 'fedizhelloworld' application
example that ships with Fediz, which is deployed in Apache Tomcat, using
Keycloak as the SAML SSO IdP. We will show how to deploy and secure the application both manually and also by a docker image that I have created for quick deployment.
1) Download and configure Keycloak
Download
and install
the latest Keycloak distribution (tested with 3.4.3).
1.1) Create users in Keycloak
Start keycloak in
standalone mode by running 'sh bin/standalone.sh'. First we need to create an admin user by navigating to the following URL, and entering a password:
- http://localhost:8080/auth/
Click on the "Administration Console" link, logging on using the admin
user credentials. You will see the configuration details of the "Master"
realm. For the purposes of this demo, we will create a new realm. Hover
the mouse pointer over "Master" in the top left-hand corner, and click
on "Add realm". Create a new realm called "fediz-samlsso". Now we will create a
new user in this realm. Click on "Users" and select "Add User",
specifying "alice" as the username. Click "save" and then go to the
"Credentials" tab for "alice", and specify a password, unselecting the
"Temporary" checkbox, and reset the password.
1.2) Create a new client application in Keycloak
Now we will create a new client application for 'fedizhelloworld' in
Keycloak. Select "Clients" in the left-hand menu, and click on "Create".
Specify the following values:
- Client ID: urn:org:apache:cxf:fediz:fedizhelloworld
- Client protocol: saml
- Client SAML Endpoint: https://localhost:9443/fedizhelloworld/secure
Once the client is created you will see more configuration options:
- Select "Sign Assertions"
- Select "Force Name ID Format".
- Valid Redirect URIs: https://localhost:9443/*
Click 'Save'. Now go to the "SAML Keys" tab of the newly created client. Here we will
have to import the certificate of the Fediz RP so that Keycloak can
validate the signed SAML requests. Click "Import" and specify:
- Archive Format: JKS
- Key Alias: mytomrpkey
- Store password: tompass
- Import file: rp-ssl-key.jks
1.3) Export the Keycloak signing certificate
Finally, we need to export the Keycloak signing certificate so that the
Fediz plugin can validate the signed SAML Response from Keycloak. Select
"Realm Settings" (for "fediz-samlsso") and click on the "Keys" tab. Copy and
save the value specified in the "Certificate" textfield.
2) Manually configure 'fedizhelloworld' application in Apache Tomcat
In this section, we'll look at manually configuring the 'fedizhelloworld' application in Apache Tomcat. To use a docker image skip to the next section.
Download and extract Apache Tomcat 8 (tested with 8.5.32) to ${catalina.home}.
Download
Fediz 1.4.4 and build the source with "mvn clean install -DskipTests".
Copy 'apache-fediz/target/apache-fediz-1.4.4' to a new directory
(${fediz.home}).
2.1) Secure the Apache Tomcat container with the Fediz plugin
First we will secure the Apache Tomcat container with the Fediz plugin:
- Create a new directory: ${catalina.home}/lib/fediz
- Edit ${catalina.home}/conf/catalina.properties and append ',${catalina.home}/lib/fediz/*.jar' to the 'common.loader' property.
- Copy ${fediz.home}/plugins/tomcat8/lib/* to ${catalina.home}/lib/fediz
- Edit the TLS Connector in ${catalina.home}/conf/server.xml', and change the ports to avoid conflict with Keycloak, i.e. switch 8080 to 9080, 8443 to 9443, etc.
- In the same file, add configuration for the TLS port: <Connector port="9443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="rp-ssl-key.jks" keystorePass="tompass" />
2.2) Deploy 'fedizhelloworld' to Tomcat
- Do a "mvn clean install" in ${fediz.home}/examples/simpleWebapp
- Copy ${fediz.home}/examples/simpleWebapp/target/fedizhelloworld.war to ${catalina.home}/webapps.
- Copy ${fediz.home}/examples/samplekeys/rp-ssl-key.jks to ${catalina.home}.
- Copy ${fediz.home}/examples/simpleWebapp/src/main/config/fediz_config.xml to ${catalina.home}/conf/
2.3) Configure 'fediz_config.xml'
Now we need to configure '${catalina.home}/conf/fediz_config.xml' that we copied from the Fediz example in the previous section:
- Under 'contextConfig', specify the key we are using to sign the SAML Request: <signingKey keyAlias="mytomrpkey" keyPassword="tompass">
<keyStore file="rp-ssl-key.jks" password="tompass" type="JKS" />
</signingKey>
- Change the trustManager keystore to: <keyStore file="keycloak.cert" type="PEM" />
- In the 'Protocol' section, change 'federationProtocolType' to 'samlProtocolType'.
- Change the 'Issuer' value to: http://localhost:8080/auth/realms/fediz-samlsso/protocol/saml
- Under 'Protocol' add: <signRequest>true</signRequest and <disableDeflateEncoding>true</disableDeflateEncoding>
Finally, create a file called 'keycloak.cert' in ${catalina.home}. In between "-----BEGIN CERTIFICATE----- / -----END CERTIFICATE-----" tags, paste the Keycloak signing certificate as retrieved in step "1.3"
above.
3) Using a docker image to deploy 'fedizhelloworld'
I have created a simple docker project which can be used to package and deploy the 'fedizhelloworld.war' into Apache Tomcat, which is secured with Fediz. The project is available on github
here. Clone the project and build and run with the following steps:
- Edit 'keycloak.cert' and paste in the signing certificate as retrieved in step 1.3 above.
- Build with: docker build -t coheigea/fediz-samlsso-rp .
- Run with: docker run -p 9443:8443 coheigea/fediz-samlsso-rp
At the time of writing, the docker file references a SNAPSHOT build of Fediz, as 1.4.4 is not yet released.
4) Testing the service
To test the service navigate to:
- https://localhost:9443/fedizhelloworld/secure/fedservlet
You should be redirected to the Keycloak
authentication page. Enter the user credentials you have created, and you will be redirected back to the 'fedizhelloworld' application successfully.