From 3fd7bde835a37ef64d38f801cff589e1522caa82 Mon Sep 17 00:00:00 2001 From: Prarthona Paul Date: Fri, 4 Aug 2023 10:59:58 -0400 Subject: [PATCH] Added an example to deploy an OIDC secured application to OpenShift using an in-progress feature Closes https://github.com/wildfly/wildfly.org/issues/498 --- ...progress-wildfly-feature-on-openshift.adoc | 318 ++++++++++++++++++ 1 file changed, 318 insertions(+) create mode 100644 _posts/2024-01-02-in-progress-wildfly-feature-on-openshift.adoc diff --git a/_posts/2024-01-02-in-progress-wildfly-feature-on-openshift.adoc b/_posts/2024-01-02-in-progress-wildfly-feature-on-openshift.adoc new file mode 100644 index 0000000000..5dc8704bd5 --- /dev/null +++ b/_posts/2024-01-02-in-progress-wildfly-feature-on-openshift.adoc @@ -0,0 +1,318 @@ +--- +layout: post +title: 'Trying Out An Upcoming Security Feature for WildFly on OpenShift' +date: 2024-01-02 +tags: oidc authentication OpenShift scopes +synopsis: How to deploy a wildfly app on OpenShift using an upcoming feature that introduces the ability to add additional scope values when securing applications using OpenID Connect. +author: prarthonapaul +--- + +:toc: macro +:toc-title: + +A future release of wildfly will include the ability to add additional scope values when securing applications using +OpenID Connect (OIDC). This blog post demonstrates how to secure a wildfly application using OpenID Connect and configure scope +values to request additional claims using an in-progress version of the feature. This feature adds the ability to specify +additional scope values in the authentication request for applications secured using OIDC. For updates on the status +of the feature, please keep an eye on https://issues.redhat.com/browse/WFLY-16532[WFLY-16532]. +We will also walk through how to deploy this feature on the cloud using +https://developers.redhat.com/developer-sandbox[OpenShift]. + +toc::[] + +== OpenID Connect +https://openid.net/developers/how-connect-works/[OpenID Connect] is an identity layer on top of the OAuth 2.0 protocol that makes it possible for a client to verify a user’s identity based on authentication that’s performed by an OpenID provider. A future release of wildfly will allow the user to configure additional scope values to request specific claim values. + +== Prerequisites +We can deploy this application using OpenShift https://developers.redhat.com/developer-sandbox[Developer Sandbox]. There are other https://www.redhat.com/en/technologies/cloud-computing/openshift/try-it[options] available for running OpenShift. Please refer to this https://docs.wildfly.org/30/Getting_Started_on_OpenShift.html[getting started guide] to learn more about wildfly on OpenShift. We will be making use of the following tools for this walkthrough: + +* https://docs.docker.com/[Docker] (you can also use https://docs.podman.io/en/latest/[Podman]) +* https://developers.redhat.com/developer-sandbox[Developer Sandbox] +* https://docs.openshift.com/container-platform/4.14/cli_reference/openshift_cli/getting-started-cli.html[OpenShift CLI] +* https://quay.io/repository/[Quay] +* https://helm.sh/[Helm] + +== Example Application +For this walkthrough, we will be making use of the https://github.com/PrarthonaPaul/elytron-examples/tree/elytron-oidc-client-scope/elytron-oidc-client-scope[elytron-oidc-client-scope] project which makes use of the ability to configure additional scope values for OpenID Connect. First, clone the `elytron-examples` repo locally and navigate to the `elytron-oidc-client-scope` directory: +``` +git clone https://github.com/prarthonapaul/elytron-examples +git checkout elytron-oidc-client-scope +cd PATH/TO/elytron-examples/elytron-oidc-client-scope +``` + +== 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 OpenShift CLI: +``` +oc login -u myUserName +``` + +Alternatively, to log in using the API token, navigate to Developer Sandbox, click on your username at the top right corner, and click on `Copy login command`. It will redirect you to a page where you can copy your login command and paste it on your terminal. +The command will be in this format: +``` +oc login --token=myToken --server=myServerUrl +``` + +Once you have your environment set up with the required tools, we can move on to the next step to build and deploy our application on OpenShift. + +== Start Red Hat Single Sign On +Developer Sandbox gives us access to the enterprise version of Red Hat's OpenID provider: Red Hat Single Sign On (RH-SSO). On the topology view of OpenShift, click on the _Add to Project_ button at the top left and add the version of RH-SSO that is compatible with the version of OpenShift you are running and wait for it to finish deploying. Please refer to the https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.6/html/red_hat_single_sign-on_for_openshift/index[RH-SSO for OpenShift Documentation] to learn more about it. + +**Note:** If the SSO pod fails to build with the message `ERROR *** JBossAS wrapper process (1) received TERM signal ***` on the terminal, then try increasing `timeoutSeconds` and `initialDelaySeconds` for both the `livenessProbe` and the `readinessProbe` for the SSO pod. For more information, visit https://access.redhat.com/solutions/4874991[here]. + +=== OpenShift CLI +Once the RH-SSO pod has been provisioned, use the following command to find the URL for your RH-SSO instance’s Admin Console: +``` +RHSSO_URL=https://$(oc get route sso --template='{{ .spec.host }}') && +echo "" && +echo "RHSSO Admin Console: $RHSSO_URL/admin" && echo "" +``` + +=== OpenShift Web Console +Alternatively, you can click on the `Open URL` button on the `Routes` tab of the pod to be redirected to the RH-SSO landing page and click on `Administration Console`. You will be able to sign in using the admin username and password that is specified in the yaml configuration of the RH-SSO pod. + +== Configure RH-SSO + +. First log in to the RH-SSO admin console using the username and password specified in the yaml configuration for the SSO pod. + +. From here, create a realm called **myrealm**, and a client called **myclient** as follows: + +* *General settings*: + +** *Client type* (or *Client Protocol*, depending on your RH-SSO version): *OpenID Connect* + +** *Client ID: myclient* + +* *Capability config:* + +** *Authentication flow: Standard flow, Direct access grants* + +* *Login Settings:* For the *Valid Redirect URIs*, enter a `*` for now. We will come back to edit it later. + +. Navigate to the *Client Scopes* tab for *myclient*. Here you will see that some scope values are under *Assigned Default Client Scopes* field and some others are under *Assigned Optional Client Scopes* field. When client scopes are added to *Default*, the claims associated with them are automatically added to the access token you receive without the need to configure them. Changing it to *Optional* ensures that they are not included by default and you will only get access to claims if you configure the corresponding scope values. This list of scope values you see here are the values that RH-SSO allows and it varies for different OpenID providers. RH-SSO also allows you to create new scopes, but we will not be doing that for this blog. + +. Now, click on *Roles* and create two roles, *user* and *admin*. + +. Finally, create a user called *alice* whose *First Name* is *Alice* and *Last Name* is *Smith* and assign her the *user* and *admin* roles. + +. Next, navigate to the _Credentials_ tab and create a password for Alice. Toggle the _Temporary_ switch off, so you are not prompted to update the password after the first login. + +== Build Container Images for WildFly on OpenShift + +Normally to use wildfly features that have been released, we just need to add the wildfly Helm release using the chart that is already available on OpenShift. However, since we are making use of a feature that is not released yet, we will need to build our own image of wildfly from the source code and deploy our application on that. + +=== Clone the WildFly and Elytron Projects +First we need to clone the `wildfly` and the `wildfly-elytron` projects with the branches that contain the OIDC scope feature: +``` +git clone https://github.com/PrarthonaPaul/wildfly.git +git checkout WFLY-16532 +``` +Next, go to the directory where the `wildfly-elytron` project should be cloned and clone it: +``` +git clone https://github.com/PrarthonaPaul/wildfly-elytron.git +git checkout WFLY-16532 +``` +Notice that we are not using `wildfly/wildfly` and the `wildfly-security/wildfly-elytron` repositories. Instead, we are +using a forked versions of the projects. This feature does not add any changes to the `wildfly-core` project. However, +to ensure that the branch for `wildfly-Core` is compatible with the branches in the `wildfly` and the `wildfly-elytron` +projects, we have created a branch called `WFLY-16532`, which we will use for this guide. +``` +git clone https://github.com/PrarthonaPaul/wildfly-core.git +git checkout WFLY-16532 +``` + +=== Build the WildFly Project +Next, we need to build these projects to use the local version of the code. To do this, we will specify the SNAPSHOT versions of `Elytron` and `wildfly-core`: +``` +cd /PATH/TO/wildfly-elytron +mvn clean install -DskipTests + +cd /PATH/TO/wildfly-core +mvn clean install -DskipTests -Dversion.org.wildfly.security.elytron= + +cd /PATH/TO/wildfly +mvn clean install -DskipTests -Dversion.org.wildfly.core= +``` +The `-DskipTests` tag skips all the tests, since we only need to build the projects. You can also go in and manually update the versions in the main pom.xml files of the projects and then use maven to build them. + +=== Build the Docker Image for Quay +In order to deploy our application on OpenShift, we need to first create a container image of the application using Docker or Podman. In this post we are using Docker, but you can also use Podman using the `podman` keyword, or using an alias. + +Navigate to the `wildfly` project and create a `Dockerfile` inside the root directory of the project. We will be creating an image of the current version of wildfly using the `wildfly-runtime-jdk` image on Quay. Quay is a repository for building and storing container images of your projects. + +Head over to https://quay.io/repository/[Quay.io] and create a repository called `wildfly`. For more information on how to create one, visit the https://docs.quay.io/guides/create-repo.html#:~:text=via%20the%20UI-,To%20create%20a%20repository%20in%20the%20Quay.io%20UI%2C%20click,the%20'Create%20Repository'%20button[Quay documentation]. + +Now we can create the container image for our wildfly project. Enter the following commands inside your Dockerfile: + +[source,bash] +``` +FROM quay.io/wildfly/wildfly-runtime-jdk11:latest +COPY --chown=jboss:root dist/target/wildfly-31.0.0.Beta1-SNAPSHOT $JBOSS_HOME +RUN chmod -R ug+rwX $JBOSS_HOME +``` +Please note that the wildfly version may be different for you. Please update the version to match the wildfly version you have built in previous step. +Now run the following commands on your terminal from the wildfly directory to create an image and push it to your Quay repository: +[source,bash] +``` +docker build -t quay.io//wildfly:wildfly-app . +docker push quay.io//wildfly:wildfly-app +``` +Replace `` with your username for Quay. The `-t` command indicates that we are specifying a tag, which in this case is `wildfly-app`. The tag is used to identify different images inside the same repository. Using this image, we can ensure that we are running your local version of wildfly, as opposed to the version of wildfly that is present on OpenShift. +You may need to log into quay.io using your username and password if you have not done so already using the command below: + +[source,bash] +``` +docker login -u= -p= quay.io +``` +== Build the Application + +Now that we have our wildfly container image, we can use it to deploy our application on it. Navigate to the `elytron-examples/elytron-oidc-client-scope` directory and create a deployment file for your application using this command: +``` +mvn clean package +``` +This will create a `simple-webapp-oidc.war` file inside the `target` directory. + +Next, create a new `Dockerfile` inside the `elytron-oidc-client-scope` project with the following commands inside it: +[source,bash] +``` +FROM quay.io//wildfly:wildfly-app +ADD target/simple-webapp-oidc.war /opt/server/standalone/deployments/ +``` +Here, we are making use of the container image of wildfly we made earlier and copying over the deployment file to the container image so we can deploy it on OpenShift by running the server. Next, build and push a new image of your application using the following commands: +[source,bash] +``` +docker build -t quay.io//wildfly:latest . +docker push quay.io//wildfly:latest +``` + +Notice that we have added a `.` at the end of the first command. This is to indicate the path to the project for which we are creating an image. If you are not running it from the directory of the project whose image you are trying to build, then replace the `.` with the path to the project. + +=== Configure Image Pull Secret + +In order to pull the image from Quay, you will need to configure a pull secret and connect it to your helm release. If you have already configured a pull secret for Quay, then you can skip this step. + +Navigate to your Quay console, click on `Account Settings`, `Generate Encrypted Password` and log in. Under the `Kubernetes Secret` tab you will be able to download the yaml file for your Kubernetes secret. Upload it to your OpenShift Secrets by going to the `Secret` tab on Developer Sandbox, clicking on `Create`, `From Yaml` and replacing it with the contents of your Kubernetes Secret. + +Alternatively you can link your pull secret so OpenShift can automatically use your pull secret to obtain the image when needed. You can learn more about handling secrets on OpenShift on https://docs.openshift.com/container-platform/4.14/openshift_images/managing_images/using-image-pull-secrets.html[their documentation]. + +== Add Helm Configuration + +Lastly, we will be creating a helm release of our local wildfly image and use that to deploy our application on OpenShift using a helm chart. Navigate to `charts` directory and open the `helm.yaml` file. +``` +cd /PATH/TO/ELYTRON/EXAMPLES/elytron-oidc-client-scope/charts +``` +The contents of the file will be as follows: +``` +image: + name: quay.io//wildfly +build: + enabled: false +deploy: + env: + - name: OIDC_PROVIDER_URL + value: ''/auth/ + - name: WILDFLY_OVERRIDING_ENV_VARS + value: "1" + - name: SUBSYSTEM_LOGGING_PATTERN_FORMATTER_COLOR_PATTERN__PATTERN + value: "[redhat-openshift] %-5p %s%e%n" +``` +Replace to match the url for your RH-SSO instance on OpenShift and add a `/auth/` to the end of the +URL as seen above. There are three fields that we have specified: image, build and deploy. + +Using the image field, we are specifying that we want the pod to use the image of our application that we just built. +Notice that we did not specify the tag corresponding to our Quay image. This is because when the helm chart uploads, the `latest` tag is appended to it +by default, which is why we tagged our application image as that. If you want to use a different tag, then you can edit +this by clicking on the 3 dots at the bottom of the pod, click on *Edit Deployment* and changing it under *Image Name*. + +We have also added some environment variables. Notice the `OIDC_PROVIDER_URL`. The value of this will be the url for +your RH-SSO pod, which can be found by clicking on the `Open URL` button on the pod. So, copy that link and paste it as +the `value`. The `OIDC_PROVIDER_URL` variable is being used by the `oidc.json` file inside the `WEB-INF` directory when +specifying the `provider-url`. + +Change the image name on the `charts/helm.yaml` file to include your quay username instead of . + +== Deploy the Example Application to WildFly on OpenShift +Use the following commands to deploy your webapp on OpenShift using the wildfly helm chart: +``` +helm repo add wildfly https://docs.wildfly.org/wildfly-charts/ +helm install simple-webapp-oidc -f charts/helm.yaml wildfly/wildfly +``` +After running the commands above, you should expect to see the following output: +``` +Waited for 1.068205845s due to client-side throttling, not priority and fairness, +request: GET:https://api.sandbox-m4.g2pi.p1.openshiftapps.com:6443/apis/triggers.tekton.dev/v1beta1?timeout=32s +NAME: simple-webapp-oidc +LAST DEPLOYED: +NAMESPACE: +STATUS: deployed +REVISION: 1 +TEST SUITE: None +NOTES: +To follow the deployment of your application, run: + +$ oc get deployment simple-webapp-oidc -w +``` +At this point, if you see that the deployment is failing, you can fix it by clicking on the three dots beside the `simple-webapp-oidc` pod's name and click on *Edit Deployment*. +Make sure that the image name is *quay.io//wildfly:latest*. If not, edit it to reflect the correct +image name under *Image Name*. Under *Show advanced image options*, set the *Pull Secret* to be the one you configured +in the last section and click *Save*. + +Your application is now deploying. Click on the *simple-webapp-oidc* pod and under the *resources* tab, you should see +the status of your deployment. Alternatively, you can use the following commands: +``` +$ oc get deployment simple-webapp-oidc -w +``` + +== Get the Application URL + +Just like RH-SSO, you can find the url for your webapp by clicking on `Open URL` which will redirect you to the wildfly landing page. Alternatively, you can use the OC client to do this using the following commands: +``` +SIMPLE_WEBAPP_OIDC_URL=https://$(oc get route simple-webapp-oidc --template='{{ .spec.host }}') && +echo "" && +echo "Application URL: $SIMPLE_WEBAPP_OIDC_URL/simple-webapp-oidc" && +echo "Valid redirect URI: $SIMPLE_WEBAPP_OIDC_URL/simple-webapp-oidc/*" && +echo "" +``` + +== Finish Configuring RH-SSO +Copy the link for your webapp and go back to the admin console for RH-SSO and add `/simple-webapp-oidc/*` +to the `Valid Redirect URIs` field. Notice that the link starts with `https`. We will be changing it to `http` since we +have not performed any ssl configuration. + +== Access the Application +Now, let’s try accessing our application using /simple-webapp-oidc. + +Click on "Access Secured Servlet". + +Now, you’ll be redirected to RH-SSO's login page. If you click on the url on the search bar, you will see the scope values specified in the `redirect-uri` field with the different scope values separated by a `+`. You will also notice that a new scope value: `openid`. This indicates that we are going to be using OpenID Connect to authenticate the user. + +Log in with `Alice` and the password that you set when configuring RH-SSO. + +Next, you’ll be redirected back to our application, and you should see the "Secured Servlet" page. That means that we were able to successfully log in to our application using the RH-SSO OpenID provider! + +This page will display the current principal, and a list of claim values obtained using the scope values you configured. This is what it will look like: +``` +Secured Servlet + +Current Principal 'alice' +Claims received using additional scope values: +Using the "profile" scope, we got User's name: Alice Smith +Using the "email" scope, we got email verified: true +Using the "microprofile-jwt" scope, we got the user's groups: [default-roles-myrealm, offline_access, admin, uma_authorization, user] +``` + +Note that the value for Current Principal may be different, since that is the client secret. + +Notice that there are no claims obtained using the `offline_access` scope. To learn more about what this scope value does, please refer to the https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess[ OpenID Documentation]. + +== Summary +This post demonstrated how to deploy an OIDC secured wildfly application on OpenShift using Developer Sandbox. We also looked into how to configure additional scope values to request specific claim values. For more details on the `elytron-oidc-client` subsystem, please check out the https://docs.wildfly.org/30/Admin_Guide.html#Elytron_OIDC_Client[documentation]. Details on the `scope` attribute will be available once the feature is released. For more details on wildfly on OpenShift, you can check out https://cloud.redhat.com/blog/getting-started-with-wildfly[this guide]. If you have any questions or comments about this new upcoming feature, please let us know over on the https://groups.google.com/g/wildfly[WildFly User Forum]. + +== Resources +* https://issues.redhat.com/browse/WFLY-16532[Jira Issue for this feature] +* https://docs.wildfly.org/30/Getting_Started_on_OpenShift.html[Getting Started with wildfly on OpenShift] +* https://docs.openshift.com/container-platform/4.14/cli_reference/openshift_cli/getting-started-cli.html[OpenShift CLI] +* https://docs.wildfly.org/30/Getting_Started_on_OpenShift.html#helm-charts[wildfly Helm Chart] +* https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.6/html/red_hat_single_sign-on_for_openshift/index[Getting started with RH-SSO on OpenShift] +* https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.6/html/server_administration_guide/index[Keycloak Server Administration Guide] +* https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.6/html/securing_applications_and_services_guide/oidc[Using OpenID Connect to secure applications and services] \ No newline at end of file