--- title: "Secure a Quarkus API with Keycloak" date: 2020-03-17T00:00:00+02:00 opensource: - Keycloak - Quarkus topics: - OpenID Connect --- [Quarkus](https://quarkus.io/) is a Java stack that is Kubernetes native, lightweight and fast. Quarkus can be used for any type of backend development, including API-enabled backends. [Keycloak](https://www.keycloak.org/) is an open source Single Sign On solution that can be used to secure APIs. In this article, I'm describing how to secure a Quarkus API with Keycloak using JWT tokens. ## Preparation As a pre-requisite, install [Maven](https://maven.apache.org/), [jq](https://stedolan.github.io/jq/download/) and [jwt-cli](https://github.com/mike-engel/jwt-cli#installation). Create a Quarkus project using either [code.quarkus.io](https://code.quarkus.io/) or Maven. Example shown below with Maven. ```sh mvn io.quarkus:quarkus-maven-plugin:1.2.0.Final:create \ -DprojectGroupId=fr.itix.test \ -DprojectArtifactId=secured-rest \ -DclassName="fr.itix.test.SecuredResource" ``` Enter the created directory. ```sh cd secured-rest ``` ## Install and configure Keycloak Download Keycloak and install it locally. ```sh curl -L -o keycloak.tgz https://downloads.jboss.org/keycloak/9.0.0/keycloak-9.0.0.tar.gz tar zxvf keycloak.tgz mv keycloak-* keycloak ``` Create the Keycloak admin user. ```sh ./keycloak/bin/add-user-keycloak.sh -u admin -r master -p secret ``` Start the Keycloak server. ```sh nohup ./keycloak/bin/standalone.sh -Djboss.socket.binding.port-offset=100 & ``` Quickly, the Keycloak admin console should be available at [localhost:8180/auth/admin/](http://localhost:8180/auth/admin/). The login is **admin** and password is **secret**. In the rest of this section, we will configure Keycloak with: * a realm named **demo** * a client named **quarkus-app** * a user named **jdoe** * two groups named **user** and **admin** Authenticate as admin on Keycloak using the **kcadm** CLI. ```sh ./keycloak/bin/kcadm.sh config credentials --server http://localhost:8180/auth --realm master --user admin --client admin-cli --password secret ``` Create a realm named **demo**. ```sh ./keycloak/bin/kcadm.sh create realms -s realm=demo -s enabled=true -o ``` Create a client named **quarkus-app**. ```sh ./keycloak/bin/kcadm.sh create clients -r demo -s 'clientId=quarkus-app' -s 'standardFlowEnabled=false' -s 'directAccessGrantsEnabled=true' -s 'serviceAccountsEnabled=true' -s 'clientAuthenticatorType=client-secret' -s 'secret=s3cr3t' ``` The framework used by Quarkus to implement security is based on [Eclipse MicroProfile - JWT RBAC Security (MP-JWT)](https://www.eclipse.org/community/eclipse_newsletter/2017/september/article2.php) and requires a claim named **groups** to hold the group membership. So, we need to create a **custom protocol mapper** to map the user's client role mapping to the **groups** claim. ```sh CLIENT_ID="$(./keycloak/bin/kcadm.sh get clients -r demo -q clientId=quarkus-app |jq -r '.[0].id')" ./keycloak/bin/kcadm.sh create clients/$CLIENT_ID/protocol-mappers/models -r demo -f - < src/main/resources/application.properties <