WildFly Elytron

Securing WildFly Apps with OIDC on Kubernetes

You can secure your WildFly applications deployed on Kubernetes with OpenID Connect (OIDC). By using OIDC to secure applications, you delegate authentication to OpenID providers. This guide shows how to secure an example application deployed to WildFly on a Kubernetes cluster running on your local machine, with OIDC using Keycloak as the OpenID provider.

Prerequisites

To follow along with this guide, you will need:

  • Roughly 15 minutes.

  • Docker or Podman.

  • A Kubernetes cluster.

    You can use a local Kubernetes cluster such as minikube, or kind.

    The steps provided in this guide use minikube.

  • Kubernetes command-line tool, kubectl.

  • A public container registry to host your application’s Docker image.

    For example, Docker Hub.

  • Helm Chart.

Example Application

We use a simple web application in this guide that consists of a single servlet. We show how to secure this servlet using OIDC. We will use the example in the simple-webapp-oidc directory in the elytron-examples repository.

To obtain this example, clone the elytron-examples repository to your local machine:

git clone git@github.com:wildfly-security-incubator/elytron-examples.git

Start Keycloak

We will be using Keycloak as our OpenID provider.

Follow the instructions, up until "Log in to the Admin Console", provided in the Get started with Keycloak on Kubernetes guide. This guide uses Keycloak with Ingress add-on enabled.

Make note of the initial admin user’s username, password, and the Keycloak Admin Console URL. You will require these values in the the next step.

Configure Keycloak

To create a realm in Keycloak, add a user and role to the realm, and create a client with which to secure your application, follow these steps:

  1. Log into the Keycloak Admin Console using the username and password you specified earlier.

  2. Create a new realm called myrealm. For more information, see the Keycloak documentation about creating a realm. Note that

  3. Add a role called user. This role will be required to access our simple web application. For more information, see the Keycloak documentation about creating a realm role.

  4. Add a new user named alice. Set an email address for this new user, we’ll use alice@example.org. For more information, see the Keycloak documentation about creating a user.

    1. Set a password for the user alice. For more information, see the Keycloak documentation about defining user credentials.

    2. Assign alice the user role From the Role Mapping tab. For more information, see the Keycloak documentation about assigning role mappings to a user.

  5. Create a new client as follows:

    1. Click the General Settings image in the top left hand corner of the admin console.

    2. Click the Clients menu item.

    3. Click the Create client button.

    4. On the Create client page set the Client type to OpenID Connect.

    5. Set the Client id as myclient.

    6. Click the Next button.

    7. On the Capability config page, select the checkboxes for Standard flow and Direct access grants.

    8. Click the Next button.

    9. On the Login settings page no action is needed at this time.

    10. Click the Save button to save the client.

Build a docker image of the application

To build a Docker image from your application so that you can push it to a container repository, such as Docker Hub, follow these steps:

  1. Navigate to the simple-webapp-oidc directory.

  2. Create a docker image.

    mvn package wildfly:image -Popenshift
     ...
    [INFO] Successfully tagged localhost/simple-webapp-oidc:latest
    [INFO] acd8c6c41788a99c5b22d2c6b2e42ce024a89e2eb4fe5b4d721f9b56796e95bc
    [INFO] Successfully built application image simple-webapp-oidc:latest
  3. Verify that you see the image in Docker images.

    docker images
    ...
    REPOSITORY                       TAG         IMAGE ID      CREATED        SIZE
    localhost/simple-webapp-oidc     latest      acd8c6c41788  3 minutes ago  690 MB

Push the just created image to a container registry

To push your image to a container registry so that your application is available to Kubernetes clusters, follow these steps:

  1. Log in to the container registry.

    docker login <CONTAINER_REGISTRY>

    Substitute <CONTAINER_REGISTRY> as follows:

    • For Docker Hub, use docker.io.

  2. Create a new tag for your image.

    docker tag simple-webapp-oidc <TAGGED_IMAGE>

    Substitute <TAGGED_IMAGE> as follows:

    • For Docker Hub, use <USERNAME>/simple-webapp-oidc.

  3. Push the image to your container registry.

    $ docker push <TAGGED_IMAGE>:latest

    Substitute <TAGGED_IMAGE> as follows:

    • For Docker Hub, use the form <USERNAME>/simple-webapp-oidc.

Add Helm Configuration

To configure your application for Kubernetes deployment with Helm, follow these steps:

  1. Switch to the charts directory in the simple-webapp-oidc example.

    cd /PATH/TO/ELYTRON/EXAMPLES/simple-webapp-oidc/charts
  2. Obtain the URL for Keycloak.

    KEYCLOAK_URL=http://$(minikube ip):$(kubectl get services/keycloak -o go-template='{{(index .spec.ports 0).nodePort}}') &&
    echo "" &&
    echo "Keycloak URL:   $KEYCLOAK_URL" &&
    echo ""
  3. Update the values.yml file.

    image:
      name: <IMAGE_NAME>
    build:
      enabled: false # The build part is not needed since we have already built our application with the wildfly-maven-plugin plugin
    deploy:
      route:
        enabled: false # the route can be enabled, but only for OpenShift clusters
      env:
        - name: OIDC_PROVIDER_URL
          value: <KEYCLOAK_URL>

    Replace <IMAGE_NAME> with the name of the image, as follows:

    • If you used Docker Hub, add the name in the form <USERNAME>/simple-webapp-oidc.

    Replace <KEYCLOAK_URL> with the value you obtained in the previous step.

Deploy the Example Application to Kubernetes

To deploy your application to Kubernetes with Helm, follow these steps:

  1. If you haven’t already installed the WildFly Helm chart, install it:

    helm repo add wildfly https://docs.wildfly.org/wildfly-charts/
  2. If you’ve already installed the WildFly Helm Chart, be sure to update it to ensure you have the latest one:

    helm repo update
  3. Deploy the example application to WildFly on Kubernetes using the WildFly Helm Chart:

    helm install oidc-app -f /PATH/TO/ELYTRON/EXAMPLES/simple-webapp-oidc/charts/values.yaml wildfly/wildfly

    Notice that this command specifies the file we updated, values.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

Behind the Scenes

While our application is building, let’s take a closer look at our application.

  • Examine the pom.xml file.

    Notice that it contains an openshift profile. A profile in Maven lets you create a set of configuration values to customize your application build for different environments. The openshift profile in this example defines a configuration that will be used by the WildFly Helm Chart when provisioning the WildFly server on Kubernetes.

    <profiles>
        <profile>
            <id>openshift</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.wildfly.plugins</groupId>
                        <artifactId>wildfly-maven-plugin</artifactId>         (1)
                        <version>${version.wildfly.maven.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-packs>
                            <layers>
                                <layer>cloud-server</layer>
                                <layer>elytron-oidc-client</layer>           (2)
                            </layers>
                            <filename>simple-webapp-oidc.war</filename>
                        </configuration>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
    1 wildfly-maven-plugin provisions a WildFly server with the specified layers with our application deployed.
    2 elytron-oidc-client automatically adds the native OIDC client subsystem to our WildFly installation.
  • Examine the web.xml.

    ...
        <login-config>
            <auth-method>OIDC</auth-method>  (1)
        </login-config>
    ...
    1 When elytron-oidc-client subsystem sees auth-method is set to OIDC, it enables OIDC authentication mechanism for the application.
  • Examine the oidc.json file. The oidc.json is used to configure the native OIDC client subsystem.

    {
        "client-id" : "myclient",                                                         (1)
        "provider-url" : "${env.OIDC_PROVIDER_URL:http://localhost:8080}/realms/myrealm", (2)
        "public-client" : "true",                                                         (3)
        "principal-attribute" : "preferred_username",                                     (4)
        "ssl-required" : "EXTERNAL"                                                       (5)
    }
    1 This is the client we created in Keycloak.
    2 The provider URL, which is the URL for the realm myrealm that we created, is specified as an environment variable. We have set its value in the helm configuration.
    3 When public-client set to true, client credentials are not sent when communicating with the OpenID provider.
    4 We specify that the user name of the identity, which in our case is alice, is to be used as the principal for the identity.
    5 When ssl-required is set to EXTERNAL, only the communication with external clients happens over HTTPs

Set up access to the application

Set up access to your application by configuring port-forward in kubernetes.

  1. Get the name of pod for your application:

    kubectl get pod
    
    NAME                        READY   STATUS    RESTARTS      AGE
    keycloak-65766c8d6b-tdnhn   1/1     Running   1 (19m ago)   52m
    oidc-app-5d6f9974fd-srvrg   1/1     Running   0             4m

    In the example, the pod name is oidc-app-5d6f9974fd-srvrg.

  2. Set port-forward:

    kubectl port-forward <POD_NAME> 8080:8080

    Replace <POD_NAME> with the pod name obtained in the previous step.

Finish Configuring Keycloak

  1. Click the General Settings image in the top left hand corner of the admin console.

  2. Click the Clients menu item.

  3. Click myclient from the list on the Clients page.

  4. Scroll down to the Access settings section on the page.

  5. In field, Valid redirect URIs set the value to http://localhost:8080/simple-webapp-oidc/secured/*.

  6. Click the Save button at the bottom of the page.

Access the Application

To access your application, follow these steps:

  1. From your browser, navigate to http://localhost:8080/simple-webapp-oidc.

  2. Click on Access Secured Servlet.

    You will be redirected to Keycloak to log in.

  3. 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 name of the logged in user.

You should see the following output:

Secured Servlet

Current Principal 'alice'

This indicates that we have successfully logged into our application!

Summary

This guide has shown how to secure an application deployed to WildFly on Kubernetes with OIDC. For additional information, feel free to check out the resources linked below.