Keycloak is a great open-source authentication (now also authorization/access control) server particularly suited for applications consisting of many (micro)services. To make it easier to secure applications on WildFly and other runtimes, Keycloak comes with OpenID Connect and SAML 2.0 adapters. More information on adapter installation and configuration can be found in Keycloak’s documentation.

WildFly adapter offers you 2 ways of securing your WARs – you can bundle the configuration with your application (via a keycloak.json file under your application’s WEB-INF directory), or you can secure your WAR externally using the Keycloak subsystem (in the configuration file of your server, e.g. standalone.xml). Although the former is convenient and I am a fan of keeping configuration with the application code in general, I prefer to use the latter because of its flexibility – you don’t need to modify your WAR files depending on where you deploy them, you can use the same bundles on your local development instance and in production.

The XML snippet needed to configure the subsystem is easy to obtain - you can download it through Keycloak Admin Console (select Keycloak OIDC JBoss subsystem XML under your client application’s Installation tab). Depending on your setup, the configuration will be similar to this (the realm key has been ellipsized for brevity):

<secure-deployment name="sample-application.war">
    <realm>sample-realm</realm>
    <realm-public-key>MIIBI...IDAQAB</realm-public-key>
    <auth-server-url>http://localhost:8080/auth</auth-server-url>
    <ssl-required>ALL</ssl-required>
    <resource>sample-application</resource>
    <credential name="secret">6215871c-c4c7-40ce-acd2-fee9d65acccb</credential>
</secure-deployment>

However, if you prepare your server in an automated way, e.g. through a Dockerfile, your configuration changes often, or you have many WAR files to secure, JBoss CLI is a better option. The rest of this post shows how to replicate the configuration above with CLI.

We start by setting up the realm configuration:

/subsystem=keycloak/realm=sample-realm:add(realm-public-key=MIIBI...IDAQAB,\
  auth-server-url=http://localhost:8080/auth,ssl-required=all,\
  disable-trust-manager=true)

The disable-trust-manager option disables verification of SSL certificates. As such, it should never be used in production. For development purposes, you could also disable the requirement for secure communication completely:

/subsystem=keycloak/realm=sample-realm:write-attribute\
  (name=ssl-required,value=none)
/subsystem=keycloak/realm=sample-realm:undefine-attribute\
  (name=disable-trust-manager)

In production, however, you should keep the requirement for SSL for all communication, and provide the relevant keystore file, e.g.:

/subsystem=keycloak/realm=sample-realm:write-attribute\
  (name=truststore,value=/usr/lib/jvm/java/jre/lib/security/cacerts)
/subsystem=keycloak/realm=sample-realm:write-attribute\
  (name=truststore-password,value=changeit)

Depending on your setup, you might also want to enable CORS (see the list of adapter configuration options for more information):

/subsystem=keycloak/realm=sample-realm:write-attribute\
  (name=cors-max-age,value=1000)
/subsystem=keycloak/realm=sample-realm:write-attribute\
  (name=cors-allowed-methods,value="GET, POST, PUT, DELETE, OPTIONS, HEAD")
/subsystem=keycloak/realm=sample-realm:write-attribute\
  (name=enable-cors,value=true)

After configuring the realm, we link our WAR file to it:

/subsystem=keycloak/secure-deployment=sample-application.war:\
  add(realm=sample-realm,resource=sample-application)
/subsystem=keycloak/secure-deployment=sample-application.war/credential=secret:\
  add(value=6215871c-c4c7-40ce-acd2-fee9d65acccb)

The realm configuration can be shared across multiple deployments. For example, if our application included a second WAR file, e.g. sample-application2.war, we could secure it as follows:

/subsystem=keycloak/secure-deployment=sample-application2.war:\
  add(realm=sample-realm,resource=sample-application)
/subsystem=keycloak/secure-deployment=sample-application2.war/credential=secret:\
  add(value=6215871c-c4c7-40ce-acd2-fee9d65acccb)

The examples in this post were tested using WildFly 10.0.0.Final and Keycloak 2.0.0.Final.