Keycloak OAuth Policy

Description

A Keycloak-specific OAuth2 policy to regulate access to APIs. This plugin enables a wide range of sophisticated auth facilities in combination with, for instance, Keycloak’s federation, brokering and user management capabilities. An exploration of the basics can be found in our blog, but we encourage users to explore the project documentation, as there is a tremendous depth and breadth of functionality, most of which works extremely well with Apiman.

Keycloak’s token format and auth mechanism facilitate excellent performance characteristics, with users able to easily tune the setup to meet their security requirements.

In general, this is one of the best approaches for achieving security without greatly impacting performance.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-keycloak-oauth-policy",
    "version": "3.1.0-SNAPSHOT"
}

Configuration

Table 1. Keycloak oauth2 policy configuration
Option Type Description Default

requireOauth

Boolean

Require auth token Terminate request if no OAuth token is provided.

true

requireTransportSecurity

Boolean

Require transport security Any request used without transport security will be rejected. OAuth2 requires transport security (e.g. TLS, SSL) to provide protection against replay attacks. It is strongly advised for this option to be switched on

true

blacklistUnsafeTokens

Boolean

Blacklist unsafe tokens Any tokens used without transport security will be blackedlisted in all gateways to mitigate associated security risks. Uses distributed data store to share blacklist

true

stripTokens

Boolean

Strip tokens Remove any Authorization header or token query parameter before forwarding traffic to the API

true

realm

String

Realm name If you are using KeyCloak 1.2.0x or later this must be a full iss domain path (e.g. mykeycloak.local/auth/realms/apimanrealm); pre-1.2.0x simply use the realm name (e.g. apimanrealm).

Empty

realmCertificateString

String

Keycloak Realm Certificate To validate OAuth2 requests. Must be a PEM-encoded X.509 certificate. This can be copied from the Keycloak console.

Empty

delegateKerberosTicket

Boolean

Delegate Kerberos Ticket Delegate any Kerberos Ticket embedded in the Keycloak token to the API (via the Authorization header).

false

forwardRoles

forwardRoles[]

Forward Keycloak roles Set whether to forward roles to an authorization policy.

None

forwardAuthInfo

forwardAuthInfo[]

Forward auth information Set auth information from the token into header(s).

None

forwardRoles

Table 2. Forward Keycloak roles to the Authorization policy. You should specify your required role(s) in the Authorization policy’s configuration.
Option Type Description Default

active

Boolean

Forward roles Opt whether to forward any type of roles. By default these will be realm roles unless the applicationName option is also provided.

false

applicationName (optional)

String

Application Name Which application roles to forward. Note that you cannot presently forward realm and application roles, only one or the other.

Empty

forwardAuthInfo

Fields from the token can be set as headers and forwarded to the API. All standard claims, custom claims and ID token fields are available (case sensitive). A special value of access_token will forward the entire encoded token. Nested claims can be accessed by using javascript dot syntax (e.g: address.country, address.formatted).
Table 3. Forward Keycloak token information
Option Type Description Default

headers

String

Header The header value to set (to paired field).

None

field

String

Field The token field name.

None

Sample Configuration

{
  "requireOauth": true,
  "requireTransportSecurity": true,
  "blacklistUnsafeTokens": false,
  "stripTokens": false,
  "realm": "apiman-is-cool",
  "realmCertificateString": "Y29uZ3JhdHVsYXRpb25zLCB5b3UgZm91bmQgdGhlIHNlY3JldCByb29tLiB5b3VyIHByaXplIGlzIGEgZnJlZSBkb3dubG9hZCBvZiBhcGltYW4h",
  "forwardRoles": {
    "active": true
  },
  "delegateKerberosTicket": false,
  "forwardAuthInfo": [
    {
      "headers": "X-COUNTRY",
      "field": "address.country"
    },
    {
      "headers": "X-USERNAME",
      "field": "preferred_username"
    }
  ]
}