Using App ID to secure Docker and Kubernetes applications
So, you have a server side application, and you need to be able to authenticate your users without the hassle? Then App ID is for you. In this blog, will walk through the steps to use App ID to secure a servlet running in an IBM WebSphere Liberty application server that you want to deploy as a Docker image on to the Kubernetes based IBM Cloud Container Service.
We’ll show you how to bind an instance of the App ID service to your Kubernetes cluster. This will ensure that your App ID instance metadata and credentials will be available at startup as Kuberenetes Secrets, so you can protect your servlet with App ID. This part is relevant for other types of server side applications running on Kubernetes as well.
In this blog we included a sample app running on IBM Websphere Liberty application server that is protected with App ID. You can follow the tutorial blog to learn how to bind App ID to your Kubernetes Cluster, run the sample app on Kubernetes, and take a look at how the app is configured to be protected with App ID.
Before you can get started, you’ll need to complete the following prerequisites.
Install the required CLIs and create a lite cluster. To work with the IBM Cloud Container Service, you’ll need to install the IBM Cloud CLI, the Docker CLI, the Kubernetes CLI, the IBM Cloud Container Service plugin and the IBM Cloud Container Registry plugin. You can follow this easy to use Creating clusterstutorial for a step by step guide.
Create an image repository namespace. You follow steps 1 through 4 of the tutorial Deploying apps into clusters for help.
Install Maven. This is required to build the provided sample.
Configuring the sample
You should now have the CLIs installed, a lite cluster, and an image repository namespace in IBM Cloud Container Registry. The following steps assume that you are using the default cluster namespace.
Pro tip: Don’t confuse the image repository namespace and the cluster namespace. They are different namespaces.Pro tip: To use a different cluster namespace, add the –namespace= parameter to the kubectl commands.
In your terminal, log in to IBM Cloud.
Run the following command
CLUSTER_NAME=<your Kubernetes cluster name> bx cs cluster-config $CLUSTER_NAME
The output would be
export KUBECONFIG=.... Copy and paste it at your terminal to set this variable to your env.
Replace the variables in the following commands with the values appropriate for your app and execute them in terminal.
Set a value to region where you want to create the App ID instance at. This should match the region you used when creating the cluster and repository namespace. Call
bx regionsfor a list of available regions and set the selected name:
REGION=<region name, e.g. us-south>
Set the domain for your containers registry, according to the region you selected. See: registry regions for available registries domains
REGISTRY_DOMAIN=<registry domain, e.g. registry.ng.bluemix.net>
Set you repository namespace. Call
bx cr namespacesfor a list of available namesapces
REPOSITORY_NAMESPACE=<your repository namespace>
Set the name of your app ID instance
APPID_INSTANCE_NAME=<your choice of an App ID instance name>
Create an instance of App ID.
bx resource service-instance-create $APPID_INSTANCE_NAME appid graduated-tier $REGION
Optional: Change App ID instance configuration from your [IBM Cloud console](https://console.bluemix.net/dashboard/apps/)
Bind the instance of App ID that you created to your cluster.
bx cs cluster-service-bind $CLUSTER_NAME default $APPID_INSTANCE_NAME
Get the sample source from github repository appid-samples or clone it:
git clone firstname.lastname@example.org:IBM-Cloud/appid-samples.git
then go into the appid-liberty-docker folder
Change directories so that you’re in the folder in which you extracted the sample and run:
cd WebApplication; mvn clean install; cd -
Running Docker locally
Optionally, prior to pushing the sample to Kubernetes, you might want to try out running on Docker locally. When you are developing this helps you try code quickly.
To run locally, you need to get the App ID service instance credentials. You can get the credentials by doing one of the following:
Go to the Service Credentials tab of your instance dashboard.
You can decode your Kubernetes secret which you get as Base64 encoded when calling:
kubectl get secret binding-$APPID_INSTANCE_NAME -o json
I have jq installed locally so I used it to decode the value this way:
BINDING=$(kubectl get secret binding-$APPID_INSTANCE_NAME -o json | jq .data -r | jq .binding -r | base64 --decode)
Pro tip: This step eventually replaces the
APPID_AUTH_SERVER_ISSUERvalues in your Liberty/server.xml with values that we append at runtime to the server Liberty/bootstrap.properties file. You can replace them manually, just don’t pass the
--build-arg binding_secret=$BINDINGargument to the command below.
You will now need to configure the OAuth redirect URL at the App ID dashboard. Go to your App ID instance at [IBM Cloud console](https://console.bluemix.net/dashboard/apps/)
and under Identity Providers->Manage->Add web redirect URLs and add the following URL:
Run the following command to build and run the image.
APP_VERSION=1.1 docker rm appid_on_liberty docker build -t $REGISTRY_DOMAIN/$REPOSITORY_NAMESPACE/appid-liberty:$APP_VERSION . --no-cache --build-arg binding_secret=$BINDING docker run --name appid_on_liberty -i -p 80:9080 -p 443:9443 $REGISTRY_DOMAIN/$REPOSITORY_NAMESPACE/appid-liberty:$APP_VERSION
To see the sample running go to: http://localhost/appidSample.
You will see a page similar to the following in your browser:
Your sample app is now configured to allow login with an identity provider, get a token from App ID’s authorization endpoint, and use it to access the sample’s ProtectedServlet.
Pro tip: To stop the server, open another terminal and run:
docker kill appid_on_liberty
Running on IBM Cloud Container Service
You can use Kubernetes techniques in IBM Cloud Container Service to deploy apps and to ensure your apps are up and running at all times.
Find your cluster Public IP:
bx cs workers $CLUSTER_NAME
Set your IP:
Edit the image name field of the deployment section in the appid-liberty-sample.yml file to match your image name. To find the name of your image:
Edit the Binding secret name field in the appid-liberty-sample.yml file to match yours. To find your secret name:
Optional: Change the value of metadata.namespace from default to your cluster namespace if you’re using a different namespace
Build your Docker image. In an IBM Cloud Container Service Lite Cluster, we have to create the services with Node ports that have non standard http and https ports in the 30000-32767 range. In this example we chose http to be exposed at port 30080 and https at port 30081.
APP_VERSION=1.1 docker build -t $REGISTRY_DOMAIN/$REPOSITORY_NAMESPACE/appid-liberty:$APP_VERSION . \ --no-cache --build-arg clusterIP=$CLUSTER_IP --build-arg sslPort=30081
Push the image.
docker push $REGISTRY_DOMAIN/$REPOSITORY_NAMESPACE/appid-liberty:$APP_VERSION kubectl apply -f appid-liberty-sample.yml
Now configure the OAuth redirect URL at the App ID dashboard so it will approve redirecting to your cluster. Go to your App ID instance at [IBM Cloud console](https://console.bluemix.net/dashboard/apps/)
and under Identity Providers->Manage->Add web redirect URLs add the following URL:
Give the server a minute to get up and running and then you’ll be able to see your sample running on Kubernetes in IBM Cloud.