JBoss.orgCommunity Documentation

Keycloak Reference Guide

SSO for Web Apps and REST Services

1.2.1.Smartling-SNAPSHOT


Preface
1. License
2. Overview
2.1. Key Concepts in Keycloak
2.2. How Does Security Work in Keycloak?
2.2.1. Permission Scopes
3. Installation and Configuration of Keycloak Server
3.1. Installation
3.1.1. Install Standalone Server
3.1.2. Install on existing WildFly 8.2.0.Final
3.1.3. Install on existing EAP 6.4.0.GA
3.1.4. Install Development Bundle
3.2. Configuring the Server
3.2.1. Relational Database Configuration
3.2.2. MongoDB based model
3.2.3. JSON File based model
3.2.4. Outgoing Server HTTP Requests
3.2.5. SSL/HTTPS Requirement/Modes
3.2.6. SSL/HTTPS Setup
3.3. Adding Keycloak server in Domain Mode
3.4. Installing Keycloak Server as Root Context
4. Providers and SPIs
4.1. Implementing a SPI
4.2. Registering provider implementations
4.2.1. Register a provider using Modules
4.2.2. Register a provider using file-system
4.2.3. Configuring a provider
4.3. Available SPIs
5. Running Keycloak Server on OpenShift
5.1. Create Keycloak instance with the web tool
5.2. Create Keycloak instance with the command-line tool
5.3. Next steps
6. Master Admin Access Control
6.1. Global Roles
6.2. Realm Specific Roles
7. Per Realm Admin Access Control
7.1. Realm Roles
8. Adapters
8.1. General Adapter Config
8.2. JBoss/Wildfly Adapter
8.2.1. Adapter Installation
8.2.2. Required Per WAR Configuration
8.2.3. Securing WARs via Keycloak Subsystem
8.3. Tomcat 6, 7 and 8 Adapters
8.3.1. Adapter Installation
8.3.2. Required Per WAR Configuration
8.4. Jetty 9.x Adapters
8.4.1. Adapter Installation
8.4.2. Required Per WAR Configuration
8.5. Jetty 8.1.x Adapter
8.5.1. Adapter Installation
8.5.2. Required Per WAR Configuration
8.6. JBoss Fuse and Apache Karaf Adapter
8.7. Javascript Adapter
8.7.1. Session status iframe
8.7.2. Older browsers
8.7.3. JavaScript Adapter reference
8.8. Spring Boot Adapter
8.8.1. Adapter Installation
8.8.2. Required Spring Boot Adapter Configuration
8.9. Spring Security Adapter
8.9.1. Adapter Installation
8.9.2. Spring Security Configuration
8.9.3. Naming Security Roles
8.9.4. Client to Client Support
8.9.5. Spring Boot Configuration
8.10. Installed Applications
8.10.1. http://localhost
8.10.2. urn:ietf:wg:oauth:2.0:oob
8.11. Logout
8.12. Multi Tenancy
8.13. JAAS plugin
9. Identity Broker
9.1. Overview
9.2. Configuration
9.3. Social Identity Providers
9.3.1. Google
9.3.2. Facebook
9.3.3. Twitter
9.3.4. Github
9.3.5. LinkedIn
9.3.6. StackOverflow
9.4. SAML v2.0 Identity Providers
9.5. OpenID Connect v1.0 Identity Providers
9.6. Retrieving Tokens from Identity Providers
9.7. Automatically Select and Identity Provider
9.8. Mapping/Importing SAML and OIDC Metadata
9.9. Examples
10. Themes
10.1. Theme types
10.2. Configure theme
10.3. Default themes
10.4. Creating a theme
10.4.1. Stylesheets
10.4.2. Scripts
10.4.3. Images
10.4.4. Messages
10.4.5. Modifying HTML
10.5. Deploying themes
10.6. SPIs
10.6.1. Account SPI
10.6.2. Login SPI
11. Email
11.1. Email Server Config
11.1.1. Enable SSL or TLS
11.1.2. Authentication
12. Client Access Types
13. Roles
13.1. Composite Roles
14. Direct Access Grants
15. CORS
16. Cookie settings, Session Timeouts, and Token Lifespans
16.1. Remember Me
16.2. Session Timeouts
16.3. Token Timeouts
17. Admin REST API
18. Events
18.1. Event types
18.2. Event Listener
18.3. Event Store
18.4. Configure Events Settings for Realm
19. User Federation SPI and LDAP/AD Integration
19.1. LDAP and Active Directory Plugin
19.1.1. Edit Mode
19.1.2. Other config options
19.2. Sync of LDAP users to Keycloak
19.3. Writing your own User Federation Provider
20. Kerberos brokering
20.1. Setup of Kerberos server
20.2. Setup and configuration of Keycloak server
20.3. Setup and configuration of client machines
20.4. Example setups
20.4.1. Keycloak and FreeIPA docker image
20.4.2. ApacheDS testing Kerberos server
20.5. Credential delegation
20.6. Troubleshooting
21. Export and Import
22. Server Cache
22.1. Disabling Caches
22.2. Clear Caches
22.3. Cache Config
23. SAML SSO
23.1. SAML Entity Descriptor
24. Security Vulnerabilities
24.1. SSL/HTTPS Requirement
24.2. CSRF Attacks
24.3. Clickjacking
24.4. Compromised Access Codes
24.5. Compromised access and refresh tokens
24.6. Open redirectors
24.7. Password guess: brute force attacks
24.8. Password database compromised
24.9. SQL Injection attacks
24.10. Limiting Scope
25. Clustering
25.1. Configure a shared database
25.2. Configure Infinispan
25.3. Enable realm and user cache invalidation
25.4. Enable distributed user sessions
25.5. Start in HA mode
25.6. Enabling cluster security
25.7. Troubleshooting
26. Application Clustering
26.1. Stateless token store
26.2. Relative URI optimization
26.3. Admin URL configuration
26.4. Registration of application nodes to Keycloak
26.5. Refresh token in each request
27. Keycloak Security Proxy
27.1. Proxy Install and Run
27.2. Proxy Configuration
27.2.1. Basic Config
27.2.2. Application Config
27.3. Keycloak Identity Headers
28. Custom User Attributes
28.1. In admin console
28.2. In registration page
28.3. In user account profile page
29. OIDC Token and SAML Assertion Mappings
30. Migration from older versions
30.1. Migrate database
30.2. Migrate keycloak-server.json
30.3. Migrate providers
30.4. Migrate themes
30.5. Migrate application
30.6. Version specific migration
30.6.1. Migrating from 1.2.0.Beta1 to 1.2.0.RC1
30.6.2. Migrating from 1.1.0.Final to 1.2.0.Beta1
30.6.3. Migrating from 1.1.0.Beta2 to 1.1.0.Final
30.6.4. Migrating from 1.1.0.Beta1 to 1.1.0.Beta2
30.6.5. Migrating from 1.0.x.Final to 1.1.0.Beta1
30.6.6. Migrating from 1.0 RC-1 to RC-2
30.6.7. Migrating from 1.0 Beta 4 to RC-1
30.6.8. Migrating from 1.0 Beta 1 to Beta 4
30.6.9. Migrating from 1.0 Alpha 4 to Beta 1
30.6.10. Migrating from 1.0 Alpha 2 to Alpha 3
30.6.11. Migrating from 1.0 Alpha 1 to Alpha 2

In some of the example listings, what is meant to be displayed on one line does not fit inside the available page width. These lines have been broken up. A '\' at the end of a line means that a break has been introduced to fit in the page, with the following lines indented. So:

Let's pretend to have an extremely \
long line that \
does not fit
This one is short

Is really:

Let's pretend to have an extremely long line that does not fit
This one is short

Keycloak codebase is distributed under the ASL 2.0 license. It does not distribute any thirdparty libraries that are GPL. It does ship thirdparty libraries licensed under Apache ASL 2.0 and LGPL.

Keycloak is an SSO solution for web apps, mobile and RESTful web services. It is an authentication server where users can centrally login, logout, register, and manage their user accounts. The Keycloak admin UI can manage roles and role mappings for any application secured by Keycloak. The Keycloak Server can also be used to perform social logins via the user's favorite social media site i.e. Google, Facebook, Twitter etc.

Features:

  • SSO and Single Log Out for browser applications
  • Social Login. Enable Google, GitHub, Facebook, Twitter social login with no code required.
  • LDAP and Active Directory support.
  • Optional User Registration
  • Password and TOTP support (via Google Authenticator). Client cert auth coming soon.
  • Forgot password support. User can have an email sent to them
  • Reset password/totp. Admin can force a password reset, or set up a temporary password.
  • Not-before revocation policies per realm, application, or user.
  • User session management. Admin can view user sessions and what applications/clients have an access token. Sessions can be invalidated per realm or per user.
  • Pluggable theme and style support for user facing screens. Login, grant pages, account mgmt, and admin console all can be styled, branded, and tailored to your application and organizational needs.
  • Integrated Browser App to REST Service token propagation
  • OAuth Bearer token auth for REST Services
  • OAuth 2.0 Grant requests
  • OpenID Connect Support.
  • SAML Support.
  • CORS Support
  • CORS Web Origin management and validation
  • Completely centrally managed user and role mapping metadata. Minimal configuration at the application side
  • Admin Console for managing users, roles, role mappings, clients, user sessions and allowed CORS web origins.
  • Account Management console that allows users to manage their own account, view their open sessions, reset passwords, etc.
  • Deployable as a WAR, appliance, or on Openshift. Completely clusterable.
  • Multitenancy support. You can host and manage multiple realms for multiple organizations. In the same auth server and even within the same deployed application.
  • Identity brokering/chaining. You can make the Keycloak server a child IDP to another SAML 2.0 or OpenID Connect IDP.
  • Token claim, assertion, and attribute mappings. You can map user attributes, roles, and role names however you want into a OIDC ID Token, Access Token, SAML attribute statements, etc. This feature allows you to basically tailor however you want auth responses to look.
  • Supports JBoss AS7, EAP 6.x, Wildfly, Tomcat 7, Tomcat 8, Jetty 9.1.x, Jetty 9.2.x, Jetty 8.1.x, and Pure JavaScript applications. Plans to support Node.js, RAILS, GRAILS, and other non-Java deployments

The core concept in Keycloak is a Realm. A realm secures and manages security metadata for a set of users and registered clients. Users can be created within a specific realm within the Administration console. Roles (permission types) can be defined at the realm level and you can also set up user role mappings to assign these permissions to specific users.

A client is a service that is secured by a realm. You will often use Client for every Application secured by Keycloak. When a user browses an application's web site, the application can redirect the user agent to the Keycloak Server and request a login. Once a user is logged in, they can visit any other client (application) managed by the realm and not have to re-enter credentials. This also hold true for logging out. Roles can also be defined at the client level and assigned to specific users. Depending on the client type, you may also be able to view and manage user sessions from the administration console.

In admin console there is switch Consent required specified when creating/editing client. When on, the client is not immediately granted all permissions of the user. In addition to requesting the login credentials of the user, the Keycloak Server will also display a grant page asking the user if it is ok to grant allowed permissions to the client. The granted consents are saved and every user can see his granted consents in Account Management UI and he can also revoke them for particular client. Also admin can see and revoke the grants of particular user in Keycloak Admin Console UI.

Keycloak uses access tokens to secure web invocations. Access tokens contains security metadata specifying the identity of the user as well as the role mappings for that user. The format of these tokens is a Keycloak extension to the JSON Web Token specification. Each realm has a private and public key pair which it uses to digitally sign the access token using the JSON Web Signature specification. Applications can verify the integrity of the digitally signed access token using the public key of the realm. The protocols used to obtain this token is defined by the OAuth 2.0 specification.

The interesting thing about using these smart access tokens is that applications themselves are completely stateless as far as security metadata goes. All the information they need about the user is contained in the token and there's no need for them to store any security metadata locally other than the public key of the realm.

Signed access tokens can also be propagated by REST client requests within an Authorization header. This is great for distributed integration as applications can request a login from a client to obtain an access token, then invoke any aggregated REST invocations to other services using that access token. So, you have a distributed security model that is centrally managed, yet does not require a Keycloak Server hit per request, only for the initial login.

Keycloak Server has three downloadable distributions.

  • keycloak-1.2.1.Smartling-SNAPSHOT.[zip|tar.gz] - Standalone server
  • keycloak-overlay-1.2.1.Smartling-SNAPSHOT.[zip|tar.gz] - Installer for WildFly or JBoss EAP
  • keycloak-demo-1.2.1.Smartling-SNAPSHOT.[zip|tar.gz] - Development bundle including WildFly, Keycloak, examples and documentation

Keycloak can be installed into an existing WildFly 8.2.0.Final server. To do this download keycloak-overlay-1.2.1.Smartling-SNAPSHOT.zip or keycloak-overlay-1.2.1.Smartling-SNAPSHOT.tar.gz. Once downloaded extract into the root directory of your WildFly installation. To start WildFly with Keycloak run:

keycloak-1.2.1.Smartling-SNAPSHOT/bin/standalone.sh --server-config=standalone-keycloak.xml

or:

keycloak-1.2.1.Smartling-SNAPSHOT/bin/standalone.bat --server-config=standalone-keycloak.xml

Once the server is started log into the admin console at http://localhost:8080/auth/admin/index.html (username: admin and password: admin). Keycloak will then prompt you to enter in a new password.

To add Keycloak to other sever configurations (standalone.xml, standalone-ha.xml, etc.) open standalone/configuration/standalone-keycloak.xml and the configuration you want to add it to, for example standalone/configuration/standalone.xml. From standalone-keycloak.xml you need to copy 3 elements:

  • <extension module="org.keycloak.keycloak-subsystem"/>
  • <datasource jndi-name="java:jboss/datasources/KeycloakDS" ...>
  • <subsystem xmlns="urn:jboss:domain:keycloak:1.0" ...>

Although the Keycloak Server is designed to run out of the box, there's some things you'll need to configure before you go into production. Specifically:

  • Configuring Keycloak to use a production database.
  • Setting up SSL/HTTPS
  • Enforcing HTTPS connections

You might want to use a better relational database for Keycloak like PostgreSQL or MySQL. You might also want to tweak the configuration settings of the datasource. Please see the Wildfly documentation on how to do this.

Keycloak runs on a Hibernate/JPA backend which is configured in the standalone/configuration/keycloak-server.json. By default the setting is like this:

"connectionsJpa": {
    "default": {
        "dataSource": "java:jboss/datasources/KeycloakDS",
        "databaseSchema": "update"
    }
},

Possible configuration options are:

dataSource

JNDI name of the dataSource

jta

boolean property to specify if datasource is JTA capable

driverDialect

Value of Hibernate dialect. In most cases you don't need to specify this property as dialect will be autodetected by Hibernate.

databaseSchema

Specify if schema should be updated or validated. Valid values are "update" and "validate" ("update is default).

showSql

Specify whether Hibernate should show all SQL commands in the console (false by default)

formatSql

Specify whether Hibernate should format SQL commands (true by default)

unitName

Allow you to specify name of persistence unit if you want to provide your own persistence.xml file for JPA configuration. If this option is used, then all other configuration options are ignored as you are expected to configure all JPA/DB properties in your own persistence.xml file. Hence you can remove properties "dataSource" and "databaseSchema" in this case.

For more info about Hibernate properties, see Hibernate and JPA documentation .

Keycloak provides MongoDB based model implementation, which means that your identity data will be saved in MongoDB instead of traditional RDBMS. To configure Keycloak to use Mongo open standalone/configuration/keycloak-server.json in your favourite editor, then change:

"eventsStore": {
    "provider": "jpa",
    "jpa": {
        "exclude-events": [ "REFRESH_TOKEN" ]
    }
},

"realm": {
    "provider": "jpa"
},

"user": {
    "provider": "${keycloak.user.provider:jpa}"
},

to:

"eventsStore": {
    "provider": "mongo",
    "mongo": {
        "exclude-events": [ "REFRESH_TOKEN" ]
    }
},

"realm": {
    "provider": "mongo"
},

"user": {
    "provider": "mongo"
},

And at the end of the file add the snippet like this where you can configure details about your Mongo database:

"connectionsMongo": {
    "default": {
        "host": "127.0.0.1",
        "port": "27017",
        "db": "keycloak",
        "connectionsPerHost": 100,
        "databaseSchema": "update"
    }
}

All configuration options are optional. Default values for host and port are localhost and 27017. Default name of database is keycloak . You can also specify properties user and password if you want authenticate against your MongoDB. If user and password are not specified, Keycloak will connect unauthenticated to your MongoDB.

Finally there is set of optional configuration options, which can be used to specify connection-pooling capabilities of Mongo client. Supported int options are: connectionsPerHost, threadsAllowedToBlockForConnectionMultiplier, maxWaitTime, connectTimeout socketTimeout. Supported boolean options are: socketKeepAlive, autoConnectRetry. Supported long option is maxAutoConnectRetryTime. See Mongo documentation for details about those options and their default values.

Keycloak provides a JSON file based model implementation, which means that your identity data will be saved in a flat JSON text file instead of traditional RDBMS. The performance of this implementaion is likely to be slower because it reads and writes the entire file with each call to the Keycloak REST API. But it is very useful in development to see exactly what is being saved. It is not recommended for production.

Note that this only applies to realm and user data. There is currently no file implementation for event persistence. So you will need to use JPA or Mongo for that.

To configure Keycloak to use file persistence open standalone/configuration/keycloak-server.json in your favourite editor. Change the realm and user providers and disable caching. Change:

"realm": {
    "provider": "jpa"
},

"user": {
    "provider": "jpa"
},
    
"userSessions": {
    "provider" : "mem"
},
    
"realmCache": {
    "provider": "mem"
},

"userCache": {
    "provider": "mem",
    "mem": {
        "maxSize": 20000
    }
},

to:

"realm": {
    "provider": "file"
},

"user": {
    "provider": "file"
},
                    
"userSessions": {
    "provider" : "mem"
},
                    
"realmCache": {
    "provider": "none"
},

"userCache": {
    "provider": "none",
},

You can also change the location of the data file by adding a connectionsFile snippet:

"connectionsFile": {
   "default" : {
        "directory": "/mydirectory",
        "fileName": "myfilename.json"
    }
}

All configuration options are optional. Default value for directory is ${jboss.server.data.dir}. Default file name is keycloak-model.json.

Keycloak server needs to invoke on remote HTTP endpoints to do things like backchannel logouts and other management functions. Keycloak maintains a HTTP client connection pool which has various configuration settings you can specify before boot time. This is configured in the standalone/configuration/keycloak-server.json. By default the setting is like this:

    "connectionsHttpClient": {
        "default": {
            "disable-trust-manager": true
        }
    },

Possible configuration options are:

establish-connection-timeout-millis

Timeout for establishing a socket connection.

socket-timeout-millis

If an outgoing request does not receive data for this amount of time, timeout the connection.

connection-pool-size

How many connections can be in the pool.

max-pooled-per-route

How many connections can be pooled per host.

disable-trust-manager

If true, HTTPS server certificates are not verified. If you set this to false, you must configure a truststore.

disable-cookies

true by default. When set to true, this will disable any cookie caching.

hostname-verification-policy

WILDCARD by default. For HTTPS requests, this verifies the hostname of the server's certificate. ANY means that the hostname is not verified. WILDCARD Allows wildcards in subdomain names i.e. *.foo.com. STRICT CN must match hostname exactly.

truststore

The value is the file path to a Java keystore file. If you prefix the path with classpath:, then the truststore will be obtained from the deployment's classpath instead. HTTPS requests need a way to verify the host of the server they are talking to. This is what the trustore does. The keystore contains one or more trusted host certificates or certificate authorities.

truststore-password

Password for the truststore keystore. This is REQUIRED if truststore is set.

client-keystore

This is the file path to a Java keystore file. This keystore contains client certificate for two-way SSL.

client-keystore-password

Password for the client keystore. This is REQUIRED if client-keystore is set.

client-key-password

Not supported yet, but we will support in future versions. Password for the client's key. This is REQUIRED if client-keystore is set.

First enable SSL on Keycloak or on a reverse proxy in front of Keycloak. Then configure the Keycloak Server to enforce HTTPS connections.

The following things need to be done

  • Generate a self signed or third-party signed certificate and import it into a Java keystore using keytool.
  • Enable Wildfly to use this certificate and turn on SSL/HTTPS.

In order to allow HTTPS connections, you need to obtain a self signed or third-party signed certificate and import it into a Java keystore before you can enable HTTPS in the web container you are deploying the Keycloak Server to.

In development, you will probably not have a third party signed certificate available to test a Keycloak deployment so you'll need to generate a self-signed on. Generate one is very easy to do with the keytool utility that comes with the Java jdk.

    $ keytool -genkey -alias localhost -keyalg RSA -keystore keycloak.jks -validity 10950
        Enter keystore password: secret
        Re-enter new password: secret
        What is your first and last name?
        [Unknown]:  localhost
        What is the name of your organizational unit?
        [Unknown]:  Keycloak
        What is the name of your organization?
        [Unknown]:  Red Hat
        What is the name of your City or Locality?
        [Unknown]:  Westford
        What is the name of your State or Province?
        [Unknown]:  MA
        What is the two-letter country code for this unit?
        [Unknown]:  US
        Is CN=localhost, OU=Keycloak, O=Test, L=Westford, ST=MA, C=US correct?
        [no]:  yes
    

You should answer What is your first and last name ? question with the DNS name of the machine you're installing the server on. For testing purposes, localhost should be used. After executing this command, the keycloak.jks file will be generated in the same directory as you executed the keytool command in.

If you want a third-party signed certificate, but don't have one, you can obtain one for free at cacert.org. You'll have to do a little set up first before doing this though.

The first thing to do is generate a Certificate Request:

    $ keytool -certreq -alias yourdomain -keystore keycloak.jks > keycloak.careq
    

Where yourdomain is a DNS name for which this certificate is generated for. Keytool generates the request:

    -----BEGIN NEW CERTIFICATE REQUEST-----
    MIIC2jCCAcICAQAwZTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMREwDwYDVQQHEwhXZXN0Zm9y
    ZDEQMA4GA1UEChMHUmVkIEhhdDEQMA4GA1UECxMHUmVkIEhhdDESMBAGA1UEAxMJbG9jYWxob3N0
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr7kck2TaavlEOGbcpi9c0rncY4HhdzmY
    Ax2nZfq1eZEaIPqI5aTxwQZzzLDK9qbeAd8Ji79HzSqnRDxNYaZu7mAYhFKHgixsolE3o5Yfzbw1
    29Rvy+eUVe+WZxv5oo9wolVVpdSINIMEL2LaFhtX/c1dqiqYVpfnvFshZQaIg2nL8juzZcBjj4as
    H98gIS7khql/dkZKsw9NLvyxgJvp7PaXurX29fNf3ihG+oFrL22oFyV54BWWxXCKU/GPn61EGZGw
    Ft2qSIGLdctpMD1aJR2bcnlhEjZKDksjQZoQ5YMXaAGkcYkG6QkgrocDE2YXDbi7GIdf9MegVJ35
    2DQMpwIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUQwlZJBA+fjiDdiVzaO9vrE/i
    n2swDQYJKoZIhvcNAQELBQADggEBAC5FRvMkhal3q86tHPBYWBuTtmcSjs4qUm6V6f63frhveWHf
    PzRrI1xH272XUIeBk0gtzWo0nNZnf0mMCtUBbHhhDcG82xolikfqibZijoQZCiGiedVjHJFtniDQ
    9bMDUOXEMQ7gHZg5q6mJfNG9MbMpQaUVEEFvfGEQQxbiFK7hRWU8S23/d80e8nExgQxdJWJ6vd0X
    MzzFK6j4Dj55bJVuM7GFmfdNC52pNOD5vYe47Aqh8oajHX9XTycVtPXl45rrWAH33ftbrS8SrZ2S
    vqIFQeuLL3BaHwpl3t7j2lMWcK1p80laAxEASib/fAwrRHpLHBXRcq6uALUOZl4Alt8=
    -----END NEW CERTIFICATE REQUEST-----
     

Send this ca request to your CA. The CA will issue you a signed certificate and send it to you. Before you import your new cert, you must obtain and import the root certificate of the CA. You can download the cert from CA (ie.: root.crt) and import as follows:

    $ keytool -import -keystore keycloak.jks -file root.crt -alias root
    

Last step is import your new CA generated certificate to your keystore:

    $ keytool -import -alias yourdomain -keystore keycloak.jks -file your-certificate.cer
    

In domain mode, you start the server with the "domain" command instead of the "standalone" command. In this case, the Keycloak subsystem is defined in domain/configuration/domain.xml instead of standalone/configuration.standalone.xml. Inside domain.xml, you will see more than one profile. A Keycloak subsystem can be defined in zero or more of those profiles.

To enable Keycloak for a server profile edit domain/configuration/domain.xml. To the extensions element add the Keycloak extension:

<extensions>
    ...
    <extension module="org.keycloak.keycloak-subsystem"/>
</extensions>

Then you need to add the server to the required server profiles. By default WildFly starts two servers in the main-server-group which uses the full profile. To add Keycloak for this profile add the Keycloak subsystem to the profile element with name full:

<profile name="full">
    ...
    <subsystem xmlns="urn:jboss:domain:keycloak:1.0">
        <auth-server name="main-auth-server">
            <enabled>true</enabled>
            <web-context>auth</web-context>
        </auth-server>
    </subsystem>

To configure the server copy standalone/configuration/keycloak-server.json to domain/servers/<SERVER NAME>/configuration. The configuration should be identical for all servers in a group.

Follow the Clustering section of the documentation to configure Keycloak for clustering. In domain mode it doesn't make much sense to not configure Keycloak in cluster mode.

To deploy custom providers and themes you should deploys these as modules and make sure the modules are available to all servers in the group. See Providers and Themes sections for more information on how to do this.

Keycloak is designed to cover most use-cases without requiring custom code, but we also want it to be customizable. To achive this Keycloak has a number of SPIs which you can implement your own providers for.

To implement an SPI you need to implement it's ProviderFactory and Provider interfaces. You also need to create a provider-configuration file. For example to implement the Event Listener SPI you need to implement EventListenerProviderFactory and EventListenerProvider and also provide the file META-INF/services/org.keycloak.events.EventListenerProviderFactory

For example to implement the Event Listener SPI you start by implementing EventListenerProviderFactory:

{
package org.acme.provider;

import ...

public class MyEventListenerProviderFactory implements EventListenerProviderFactory {

    private List<Event> events;

    public String getId() {
        return "my-event-listener";
    }

    public void init(Config.Scope config) {
        int max = config.getInt("max");
        events = new MaxList(max);
    }

    public EventListenerProvider create(KeycloakSession session) {
        return new MyEventListenerProvider(events);
    }

    public void close() {
        events = null;
    }

}
}

The example uses an imagined MaxList which has a maximum size and is concurrency safe. When the maximum size is reached and new entries are added the oldest entry is removed. Keycloak creates a single instance of EventListenerProviderFactory which makes it possible to store state for multiple requests. EventListenerProvider instances are created by calling create on the factory for each requests so these should be light-weight.

Next you would implement EventListenerProvider:

{
package org.acme.provider;

import ...

public class MyEventListenerProvider implements EventListenerProvider {

    private List<Event> events;

    public MyEventListenerProvider(List<Event> events) {
        this.events = events;
    }

    @Override
    public void onEvent(Event event) {
        events.add(event);
    }

    @Override
    public void close() {

    }

}
}

The file META-INF/services/org.keycloak.events.EventListenerProviderFactory should contain the full name of your ProviderFactory implementation:

org.acme.provider.MyEventListenerProviderFactory

Keycloak can load provider implementations from JBoss Modules or directly from the file-system. Using Modules is recommended as you can control exactly what classes are available to your provider. Any providers loaded from the file-system uses a classloader with the Keycloak classloader as its parent.

Here's a list of the available SPIs and a brief description. For more details on each SPI refer to individual sections.

Account
Provides the account manage console pages. The default implementation uses FreeMarker templates.
Connections Infinispan
Loads and configures Infinispan connections. The default implementation can load connections from the Infinispan subsystem, or alternatively can be manually configured in keycloak-server.json.
Connections Jpa
Loads and configures Jpa connections. The default implementation can load datasources from WildFly/EAP, or alternatively can be manually configured in keycloak-server.json.
Connections Jpa Updater
Updates database schema. The default implementation uses Liquibase.
Connections Mongo
Loads and configures MongoDB connections. The default implementation is configured in keycloak-server.json.
Email
Formats and sends email. The default implementation uses FreeMarker templates and JavaMail.
Events Listener
Listen to user related events for example user login success and failures. Keycloak provides two implementations out of box. One that logs events to the server log and another that can send email notifications to users on certain events.
Events Store
Store user related events so they can be viewed through the admin console and account management console. Keycloak provides implementations for Relational Databases and MongoDB.
Export
Exports the Keycloak database. Keycloak provides implementations that export to JSON files either as a single file, multiple files in a directory or a encrypted ZIP archive.
Import
Imports an exported Keycloak database. Keycloak provides implementations that import from JSON files either as a single file, multiple files in a directory or a encrypted ZIP archive.
Login
Provides the login pages. The default implementation uses FreeMarker templates.
Login Protocol
Provides protocols. Keycloak provides implementations of OpenID Connect and SAML 2.0.
Realm
Provides realm and application meta-data. Keycloak provides implementations for Relational Databases and MongoDB.
Realm Cache
Caches realm and application meta-data to improve performance. Keycloak provides a basic in-memory cache and a Infinispan cache.
Theme
Allows creating themes to customize look and feel. Keycloak provides implementations that can load themes from the file-system or classpath.
Timer
Executes scheduled tasks. Keycloak provides a basic implementation based on java.util.Timer.
User
Provides users and role-mappings. Keycloak provides implementations for Relational Databases and MongoDB.
User Cache
Caches users and role-mappings to improve performance. Keycloak provides a basic in-memory cache and a Infinispan cache.
User Federation
Support syncing users from an external source. Keycloak provides implementations for LDAP and Active Directory.
User Sessions
Provides users session information. Keycloak provides implementations for basic in-memory, Infinispan, Relational Databases and MongoDB

Keycloak provides a OpenShift cartridge to make it easy to get it running on OpenShift. If you don't already have an account or don't know how to create applications go to https://www.openshift.com/ first. You can create the Keycloak instance either with the web tool or the command line tool, both approaches are described below.

Warning

It's important that immediately after creating a Keycloak instance you open the Administration Console and login to reset the password. If this is not done anyone can easily gain admin rights to your Keycloak instance.

Open https://openshift.redhat.com/app/console/applications and click on Add Application. Scroll down to the bottom of the page to find the Code Anything section. Insert http://cartreflect-claytondev.rhcloud.com/github/keycloak/openshift-keycloak-cartridge into the URL to a cartridge definition field and click on Next. Fill in the following form and click on Create Application.

Click on Continue to the application overview page. Under the list of applications you should find your Keycloak instance and the status should be Started. Click on it to open the Keycloak servers homepage.

You can create and manage multiple realms by logging into the master Keycloak admin console at /{keycloak-root}/admin/index.html

Users in the Keycloak master realm can be granted permission to manage zero or more realms that are deployed on the Keycloak server. When a realm is created, Keycloak automatically creates various roles that grant fine-grain permissions to access that new realm. Access to The Admin Console and REST endpoints can be controlled by mapping these roles to users in the master realm. It's possible to create multiple super users as well as users that have only access to certain operations in specific realms.

Administering your realm through the master realm as discussed in Chapter 6, Master Admin Access Control may not always be ideal or feasible. For example, maybe you have more than one admin application that manages various admin aspects of your organization and you want to unify all these different "admin consoles" under one realm so you can do SSO between them. Keycloak allows you to grant realm admin privileges to users within that realm. These realm admins can participate in SSO for that realm and visit a keycloak admin console instance that is dedicated solely for that realm by going to the url: /{keycloak-root}/admin/{realm}/console

Keycloak can secure a wide variety of application types. This section defines which application types are supported and how to configure and install them so that you can use Keycloak to secure your applications.

Each adapter supported by Keycloak can be configured by a simple JSON text file. This is what one might look like:

{
  "realm" : "demo",
  "resource" : "customer-portal",
  "realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB",
  "auth-server-url" : "https://localhost:8443/auth",
  "ssl-required" : "external",
  "use-resource-role-mappings" : false,
  "enable-cors" : true,
  "cors-max-age" : 1000,
  "cors-allowed-methods" : "POST, PUT, DELETE, GET",
  "bearer-only" : false,
  "enable-basic-auth" : false,
  "expose-token" : true,
   "credentials" : {
      "secret" : "234234-234234-234234"
   },

   "connection-pool-size" : 20,
   "disable-trust-manager": false,
   "allow-any-hostname" : false,
   "truststore" : "path/to/truststore.jks",
   "truststore-password" : "geheim",
   "client-keystore" : "path/to/client-keystore.jks",
   "client-keystore-password" : "geheim",
   "client-key-password" : "geheim"
}

Some of these configuration switches may be adapter specific and some are common across all adapters. For Java adapters you can use ${...} enclosure as System property replacement. For example ${jboss.server.config.dir}. Also, you can obtain a template for this config file from the admin console. Go to the realm and select the application you want a template for. Go to the Installation tab and this will provide you with a template that includes the public key of the realm.

Here is a description of each item:

realm

Name of the realm representing the users of your distributed applications and services. This is REQUIRED.

resource

Username of the application. Each application has a username that is used when the application connects with the Keycloak server to turn an access code into an access token (part of the OAuth 2.0 protocol). This is REQUIRED.

realm-public-key

PEM format of public key. You can obtain this from the administration console. This is REQUIRED.

auth-server-url

The base URL of the Keycloak Server. All other Keycloak pages and REST services are derived from this. It is usually of the form https://host:port/auth This is REQUIRED.

ssl-required

Ensures that all communication to and from the Keycloak server from the adapter is over HTTPS. This is OPTIONAL. The default value is external meaning that HTTPS is required by default for external requests. Valid values are 'all', 'external' and 'none'.

use-resource-role-mappings

If set to true, the adapter will look inside the token for application level role mappings for the user. If false, it will look at the realm level for user role mappings. This is OPTIONAL. The default value is false.

public-client

If set to true, the adapter will not send credentials for the client to Keycloak. The default value is false.

enable-cors

This enables CORS support. It will handle CORS preflight requests. It will also look into the access token to determine valid origins. This is OPTIONAL. The default value is false.

cors-max-age

If CORS is enabled, this sets the value of the Access-Control-Max-Age header. This is OPTIONAL. If not set, this header is not returned in CORS responses.

cors-allowed-methods

If CORS is enabled, this sets the value of the Access-Control-Allow-Methods header. This should be a comma-separated string. This is OPTIONAL. If not set, this header is not returned in CORS responses.

cors-allowed-headers

If CORS is enabled, this sets the value of the Access-Control-Allow-Headers header. This should be a comma-separated string. This is OPTIONAL. If not set, this header is not returned in CORS responses.

bearer-only

This tells the adapter to only do bearer token authentication. That is, it will not do OAuth 2.0 redirects, but only accept bearer tokens through the Authorization header. This is OPTIONAL. The default value is false.

enable-basic-auth

This tells the adapter to also support basic authentication. If this option is enabled, then secret must also be provided. This is OPTIONAL. The default value is false.

expose-token

If true, an authenticated browser client (via a Javascript HTTP invocation) can obtain the signed access token via the URL root/k_query_bearer_token. This is OPTIONAL. The default value is false.

credentials

Specify the credentials of the application. This is an object notation where the key is the credential type and the value is the value of the credential type. Currently only password is supported. This is REQUIRED.

connection-pool-size

Adapters will make separate HTTP invocations to the Keycloak Server to turn an access code into an access token. This config option defines how many connections to the Keycloak Server should be pooled. This is OPTIONAL. The default value is 20.

disable-trust-manager

If the Keycloak Server requires HTTPS and this config option is set to true you do not have to specify a truststore. While convenient, this setting is not recommended as you will not be verifying the host name of the Keycloak Server. This is OPTIONAL. The default value is false.

allow-any-hostname

If the Keycloak Server requires HTTPS and this config option is set to true the Keycloak Server's certificate is validated via the truststore, but host name validation is not done. This is not a recommended. This seting may be useful in test environments This is OPTIONAL. The default value is false.

truststore

This setting is for Java adapters. The value is the file path to a Java keystore file. If you prefix the path with classpath:, then the truststore will be obtained from the deployment's classpath instead. Used for outgoing HTTPS communications to the Keycloak server. Client making HTTPS requests need a way to verify the host of the server they are talking to. This is what the trustore does. The keystore contains one or more trusted host certificates or certificate authorities. You can create this truststore by extracting the public certificate of the Keycloak server's SSL keystore. This is OPTIONAL if ssl-required is none or disable-trust-manager is true.

truststore-password

Password for the truststore keystore. This is REQUIRED if truststore is set.

client-keystore

Not supported yet, but we will support in future versions. This setting is for Java adapters. This is the file path to a Java keystore file. This keystore contains client certificate for two-way SSL when the adapter makes HTTPS requests to the Keycloak server. This is OPTIONAL.

client-keystore-password

Not supported yet, but we will support in future versions. Password for the client keystore. This is REQUIRED if client-keystore is set.

client-key-password

Not supported yet, but we will support in future versions. Password for the client's key. This is REQUIRED if client-keystore is set.

auth-server-url-for-backend-requests

Alternative location of auth-server-url used just for backend requests. It must be absolute URI. Useful especially in cluster (see Relative URI Optimization) or if you would like to use https for browser requests but stick with http for backend requests etc.

always-refresh-token

If true, Keycloak will refresh token in every request. More info in Refresh token in each request .

register-node-at-startup

If true, then adapter will send registration request to Keycloak. It's false by default and useful just in cluster (See Registration of application nodes to Keycloak)

register-node-period

Period for re-registration adapter to Keycloak. Useful in cluster. See Registration of application nodes to Keycloak for details.

token-store

Possible values are session and cookie. Default is session, which means that adapter stores account info in HTTP Session. Alternative cookie means storage of info in cookie. See Stateless token store for details.

principal-attribute

OpenID Connection ID Token attribute to populate the UserPrincipal name with. If token attribute is null, defaults to sub. Possible values are sub, preferred_username, email, name, nickname, given_name, family_name.

To be able to secure WAR apps deployed on JBoss AS 7.1.1, JBoss EAP 6.x, or Wildfly, you must install and configure the Keycloak Subsystem. You then have two options to secure your WARs. You can provide a keycloak config file in your WAR and change the auth-method to KEYCLOAK within web.xml. Alternatively, you don't have to crack open your WARs at all and can apply Keycloak via the Keycloak Subsystem configuration in standalone.xml. Both methods are described in this section.

Adapters are no longer included with the appliance or war distribution.Each adapter is a separate download on the Keycloak download site. They are also available as a maven artifact.

Install on Wildfly:

$ cd $WILDFLY_HOME
$ unzip keycloak-wildfly-adapter-dist.zip

Install on JBoss EAP 6.x:

$ cd $JBOSS_HOME
$ unzip keycloak-eap6-adapter-dist.zip

Install on JBoss AS 7.1.1:

$ cd $JBOSS_HOME
$ unzip keycloak-as7-adapter-dist.zip

This zip file creates new JBoss Modules specific to the Wildfly Keycloak Adapter within your Wildfly distro.

After adding the Keycloak modules, you must then enable the Keycloak Subsystem within your app server's server configuration: domain.xml or standalone.xml.

<server xmlns="urn:jboss:domain:1.4">

    <extensions>
        <extension module="org.keycloak.keycloak-subsystem"/>
          ...
    </extensions>

    <profile>
        <subsystem xmlns="urn:jboss:domain:keycloak:1.0"/>
         ...
    </profile>

Note

For AS7, the extension module is org.keycloak.keycloak-as7-subsystem.

Finally, you must specify a shared keycloak security domain. This security domain should be used with EJBs and other components when you need the security context created in the secured web tier to be propagated to the EJBs (other EE component) you are invoking. Otherwise this configuration is optional.

<server xmlns="urn:jboss:domain:1.4">
 <subsystem xmlns="urn:jboss:domain:security:1.2">
    <security-domains>
...
      <security-domain name="keycloak">
         <authentication>
           <login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule"
                         flag="required"/>
          </authentication>
      </security-domain>
    </security-domains>

For example, if you have a JAX-RS service that is an EJB within your WEB-INF/classes directory, you'll want to annotate it with the @SecurityDomain annotation as follows:

import org.jboss.ejb3.annotation.SecurityDomain;
import org.jboss.resteasy.annotations.cache.NoCache;

import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.ArrayList;
import java.util.List;

@Path("customers")
@Stateless
@SecurityDomain("keycloak")
public class CustomerService {

    @EJB
    CustomerDB db;

    @GET
    @Produces("application/json")
    @NoCache
    @RolesAllowed("db_user")
    public List<String> getCustomers() {
        return db.getCustomers();
    }
}

We hope to improve our integration in the future so that you don't have to specify the @SecurityDomain annotation when you want to propagate a keycloak security context to the EJB tier.

This section describes how to secure a WAR directly by adding config and editing files within your WAR package.

The first thing you must do is create a keycloak.json adapter config file within the WEB-INF directory of your WAR. The format of this config file is describe in the general adapter configuration section.

Next you must set the auth-method to KEYCLOAK in web.xml. You also have to use standard servlet security to specify role-base constraints on your URLs. Here's an example pulled from one of the examples that comes distributed with Keycloak.


<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">

	<module-name>customer-portal</module-name>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Admins</web-resource-name>
            <url-pattern>/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Customers</web-resource-name>
            <url-pattern>/customers/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>user</role-name>
        </auth-constraint>
    </security-constraint>

    <security-constraint>
        <web-resource-collection>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>KEYCLOAK</auth-method>
        <realm-name>this is ignored currently/realm-name>
    </login-config>

    <security-role>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <role-name>user</role-name>
    </security-role>
</web-app>

You do not have to crack open a WAR to secure it with Keycloak. Alternatively, you can externally secure it via the Keycloak Subsystem. While you don't have to specify KEYCLOAK as an auth-method, you still have to define the security-constraints in web.xml. You do not, however, have to create a WEB-INF/keycloak.json file. This metadata is instead defined within XML in your server's domain.xml or standalone.xml subsystem configuration section.

<server xmlns="urn:jboss:domain:1.4">

  <profile>
    <subsystem xmlns="urn:jboss:domain:keycloak:1.0">
       <secure-deployment name="WAR MODULE NAME.war">
          <realm>demo</realm>
          <realm-public-key>MIGfMA0GCSqGSIb3DQEBAQUAA</realm-public-key>
          <auth-server-url>http://localhost:8081/auth</auth-server-url>
          <ssl-required>external</ssl-required>
          <resource>customer-portal</resource>
          <credential name="secret">password</credential>
       </secure-deployment>
    </subsystem>
  </profile>

The security-deployment name attribute identifies the WAR you want to secure. Its value is the module-name defined in web.xml with .war appended. The rest of the configuration corresponds pretty much one to one with the keycloak.json configuration options defined in general adapter configuration. The exception is the credential element.

To make it easier for you, you can go to the Keycloak Adminstration Console and go to the Application/Installation tab of the application this WAR is aligned with. It provides an example XML file you can cut and paste.

There is an additional convenience format for this XML if you have multiple WARs you are deployment that are secured by the same domain. This format allows you to define common configuration items in one place under the realm element.

<subsystem xmlns="urn:jboss:domain:keycloak:1.0">
    <realm name="demo">
        <realm-public-key>MIGfMA0GCSqGSIb3DQEBA</realm-public-key>
        <auth-server-url>http://localhost:8080/auth</auth-server-url>
        <ssl-required>external</ssl-required>
    </realm>
    <secure-deployment name="customer-portal.war">
        <realm>demo</realm>
        <resource>customer-portal</resource>
        <credential name="secret">password</credential>
    </secure-deployment>
    <secure-deployment name="product-portal.war">
        <realm>demo</realm>
        <resource>product-portal</resource>
        <credential name="secret">password</credential>
    </secure-deployment>
    <secure-deployment name="database.war">
        <realm>demo</realm>
        <resource>database-service</resource>
        <bearer-only>true</bearer-only>
    </secure-deployment>
</subsystem>

            

To be able to secure WAR apps deployed on Tomcat 6, 7 and 8 you must install the Keycloak Tomcat 6, 7 or 8 adapter into your Tomcat installation. You then have to provide some extra configuration in each WAR you deploy to Tomcat. Let's go over these steps.

This section describes how to secure a WAR directly by adding config and editing files within your WAR package.

The first thing you must do is create a META-INF/context.xml file in your WAR package. This is a Tomcat specific config file and you must define a Keycloak specific Valve.


<Context path="/your-context-path">
    <Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
</Context>
        

Next you must create a keycloak.json adapter config file within the WEB-INF directory of your WAR. The format of this config file is describe in the general adapter configuration section.

Finally you must specify both a login-config and use standard servlet security to specify role-base constraints on your URLs. Here's an example:


<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">

	<module-name>customer-portal</module-name>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Customers</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>user</role-name>
        </auth-constraint>
    </security-constraint>

    <security-constraint>
        <web-resource-collection>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>this is ignored currently/realm-name>
    </login-config>

    <security-role>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <role-name>user</role-name>
    </security-role>
</web-app>

Keycloak has a separate adapter for Jetty 9.1.x and Jetty 9.2.x that you will have to install into your Jetty installation. You then have to provide some extra configuration in each WAR you deploy to Jetty. Let's go over these steps.

This section describes how to secure a WAR directly by adding config and editing files within your WAR package.

The first thing you must do is create a WEB-INF/jetty-web.xml file in your WAR package. This is a Jetty specific config file and you must define a Keycloak specific authenticator within it.


<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <Get name="securityHandler">
        <Set name="authenticator">
            <New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
            </New>
        </Set>
    </Get>
</Configure>
        

Next you must create a keycloak.json adapter config file within the WEB-INF directory of your WAR. The format of this config file is describe in the general adapter configuration section.

Warning

The Jetty 9.1.x adapter will not be able to find the keycloak.json file. You will have to define all adapter settings within the jetty-web.xml file as described below.

Instead of using keycloak.json, you can define everything within the jetty-web.xml. You'll just have to figure out how the json settings match to the org.keycloak.representations.adapters.config.AdapterConfig class.


<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Get name="securityHandler">
    <Set name="authenticator">
        <New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
            <Set name="adapterConfig">
                <New class="org.keycloak.representations.adapters.config.AdapterConfig">
                    <Set name="realm">tomcat</Set>
                    <Set name="resource">customer-portal</Set>
                    <Set name="authServerUrl">http://localhost:8081/auth</Set>
                    <Set name="sslRequired">external</Set>
                    <Set name="credentials">
                        <Map>
                            <Entry>
                                <Item>secret</Item>
                                <Item>password</Item>
                            </Entry>
                        </Map>
                    </Set>
                    <Set name="realmKey">MIGfMA0GCSqGSIb3DQEBAQUAA4</Set>
                </New>
            </Set>
        </New>
    </Set>
  </Get>
</Configure>

You do not have to crack open your WAR to secure it with keycloak. Instead create the jetty-web.xml file in your webapps directory with the name of yourwar.xml. Jetty should pick it up. In this mode, you'll have to declare keycloak.json configuration directly within the xml file.

Finally you must specify both a login-config and use standard servlet security to specify role-base constraints on your URLs. Here's an example:


<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">

	<module-name>customer-portal</module-name>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Customers</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>user</role-name>
        </auth-constraint>
    </security-constraint>

    <security-constraint>
        <web-resource-collection>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>this is ignored currently</realm-name>
    </login-config>

    <security-role>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <role-name>user</role-name>
    </security-role>
</web-app>

Currently Keycloak supports securing your web applications running inside JBoss Fuse or Apache Karaf . It leverages Jetty 8 adapter as both JBoss Fuse 6.1 and Apache Karaf 3 are bundled with Jetty 8.1 server under the covers and Jetty is used for running various kinds of web applications.

What is supported for Fuse/Karaf is:

The best place to start is look at Fuse demo bundled as part of Keycloak examples in directory examples/fuse .

The Keycloak Server comes with a Javascript library you can use to secure HTML/Javascript applications. This library is referencable directly from the keycloak server. You can also download the adapter from Keycloak's download site if you want a static copy of this library. It works in the same way as other application adapters except that your browser is driving the OAuth redirect protocol rather than the server.

The disadvantage of using this approach is that you have a non-confidential, public client. This makes it more important that you register valid redirect URLs and make sure your domain name is secured.

To use this adapter, you must first configure an application (or client) through the Keycloak Admin Console. You should select public for the Client Type field. As public clients can't be verified with a client secret you are required to configure one or more valid redirect uris as well. Once you've configured the application click on the Installation tab and download the keycloak.json file. This file should be hosted in your web-server at the same root as your HTML pages. Alternatively you can either specify the URL for this file, or manually configure the adapter.

Next you have to initialize the adapter in your application. An example on how to do this is shown below.

<head>
    <script src="http://<keycloak server>/auth/js/keycloak.js"></script>
    <script>
        var keycloak = Keycloak();
        keycloak.init().success(function(authenticated) {
            alert(authenticated ? 'authenticated' : 'not authenticated');
        }).error(function() {
            alert('failed to initialize');
        });
    </script>
</head>

To specify the location of the keycloak.json file:

var keycloak = Keycloak('http://localhost:8080/myapp/keycloak.json'));

Or finally to manually configure the adapter:

var keycloak = Keycloak({
    url: 'http://keycloak-server/auth',
    realm: 'myrealm',
    clientId: 'myapp'
});

You can also pass login-required or check-sso to the init function. Login required will redirect to the login form on the server, while check-sso will redirect to the auth server to check if the user is already logged in to the realm. For example:

keycloak.init({ onLoad: 'login-required' })

After you login, your application will be able to make REST calls using bearer token authentication. Here's an example pulled from the customer-portal-js example that comes with the distribution.

<script>
    var loadData = function () {
        document.getElementById('username').innerText = keycloak.username;

        var url = 'http://localhost:8080/database/customers';

        var req = new XMLHttpRequest();
        req.open('GET', url, true);
        req.setRequestHeader('Accept', 'application/json');
        req.setRequestHeader('Authorization', 'Bearer ' + keycloak.token);

        req.onreadystatechange = function () {
            if (req.readyState == 4) {
                if (req.status == 200) {
                    var users = JSON.parse(req.responseText);
                    var html = '';
                    for (var i = 0; i < users.length; i++) {
                        html += '<p>' + users[i] + '</p>';
                    }
                    document.getElementById('customers').innerHTML = html;
                    console.log('finished loading data');
                }
            }
        }

        req.send();
    };

    var loadFailure = function () {
        document.getElementById('customers').innerHTML = '<b>Failed to load data.  Check console log</b>';

    };

    var reloadData = function () {
        keycloak.updateToken().success(loadData).error(loadFailure);
    }
</script>

<button onclick="loadData()">Submit</button>

The loadData() method builds an HTTP request setting the Authorization header to a bearer token. The keycloak.token points to the access token the browser obtained when it logged you in. The loadFailure() method is invoked on a failure. The reloadData() function calls keycloak.onValidAccessToken() passing in the loadData() and loadFailure() callbacks. The keycloak.onValidAcessToken() method checks to see if the access token hasn't expired. If it hasn't, and your oauth login returned a refresh token, this method will refresh the access token. Finally, if successful, it will invoke the success callback, which in this case is the loadData() method.

To refresh the token if it's expired call the updateToken method. This method returns a promise object which can be used to invoke a function on success or failure. This method can be used to wrap functions that should only be called with a valid token. For example the following method will refresh the token if it expires within 30 seconds, and then invoke the specified function. If the token is valid for more than 30 seconds it will just call the specified function.

keycloak.updateToken(30).success(function() {
    // send request with valid token
}).error(function() {
    alert('failed to refresh token');
);

To be able to secure Spring Boot apps you must add the Keycloak Spring Boot adapter JAR to your app. You then have to provide some extra configuration via normal Spring Boot configuration (application.properties). Let's go over these steps.

To to secure an application with Spring Security and Keyloak, add this adapter as a dependency to your project. You then have to provide some extra beans in your Spring Security configuration file and add the Keycloak security filter to your pipeline.

Unlike the other Keycloak Adapters, you should not configure your security in web.xml. However, keycloak.json is still required.

The Keycloak Spring Security adapter takes advantage of Spring Security's flexible security configuration syntax.

Keycloak provides a KeycloakWebSecurityConfigurerAdapter as a convenient base class for creating a WebSecurityConfigurer instance. The implementation allows customization by overriding methods. While its use is not required, it greatly simplifies your security context configuration.

                    
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
    /**
     * Registers the KeycloakAuthenticationProvider with the authentication manager.
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(keycloakAuthenticationProvider());
    }

    /**
     * Defines the session authentication strategy.
     */
    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        super.configure(http);
        http
                .authorizeRequests()
                .antMatchers("/customers*").hasRole("USER")
                .antMatchers("/admin*").hasRole("ADMIN")
                .anyRequest().permitAll();
    }
}

                

You must provide a session authentication strategy bean which should be of type RegisterSessionAuthenticationStrategy for public or confidential applications and NullAuthenticatedSessionStrategy for bearer-only applications.

Spring Security's SessionFixationProtectionStrategy is currently not supported because it changes the session identifier after login via Keycloak. If the session identifier changes, universal log out will not work because Keycloak is unaware of the new session identifier.

While Spring Security's XML namespace simplifies configuration, customizing the configuration can be a bit verbose.

                    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security.xsd">

    <context:component-scan base-package="org.keycloak.adapters.springsecurity" />

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="keycloakAuthenticationProvider" />
    </security:authentication-manager>

    <bean id="adapterDeploymentContextBean" class="org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean" />
    <bean id="keycloakAuthenticationEntryPoint" class="org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint" />
    <bean id="keycloakAuthenticationProvider" class="org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider" />
    <bean id="keycloakPreAuthActionsFilter" class="org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter" />
    <bean id="keycloakAuthenticationProcessingFilter" class="org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter">
        <constructor-arg name="authenticationManager" ref="authenticationManager" />
    </bean>

    <bean id="keycloakLogoutHandler" class="org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler">
            <constructor-arg ref="adapterDeploymentContextBean" />
    </bean>

    <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <constructor-arg name="logoutSuccessUrl" value="/" />
        <constructor-arg name="handlers">
            <list>
                <ref bean="keycloakLogoutHandler" />
                <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
            </list>
        </constructor-arg>
        <property name="logoutRequestMatcher">
            <bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                <constructor-arg name="pattern" value="/sso/logout**" />
                <constructor-arg name="httpMethod" value="GET" />
            </bean>
        </property>
    </bean>

    <security:http auto-config="false" entry-point-ref="keycloakAuthenticationEntryPoint">
        <security:custom-filter ref="keycloakPreAuthActionsFilter" before="LOGOUT_FILTER" />
        <security:custom-filter ref="keycloakAuthenticationProcessingFilter" before="FORM_LOGIN_FILTER" />
        <security:intercept-url pattern="/customers**" access="ROLE_USER" />
        <security:intercept-url pattern="/admin**" access="ROLE_ADMIN" />
        <security:custom-filter ref="logoutFilter" position="LOGOUT_FILTER" />
    </security:http>

</beans>

                

Multi Tenancy, in our context, means that one single target application (WAR) can be secured by a single (or clustered) Keycloak server, authenticating its users against different realms. In practice, this means that one application needs to use different keycloak.json files. For this case, there are two possible solutions:

  • The same WAR file deployed under two different names, each with its own Keycloak configuration (probably via the Keycloak Subsystem). This scenario is suitable when the number of realms is known in advance or when there's a dynamic provision of application instances. One example would be a service provider that dynamically creates servers/deployments for their clients, like a PaaS.
  • A WAR file deployed once (possibly in a cluster), that decides which realm to authenticate against based on the request parameters. This scenario is suitable when there are an undefined number of realms. One example would be a SaaS provider that have only one deployment (perhaps in a cluster) serving several companies, differentiating between clients based on the hostname (client1.acme.com, client2.acme.com) or path (/app/client1/, /app/client2/) or even via a special HTTP Header.

This chapter of the reference guide focus on this second scenario.

Keycloak provides an extension point for applications that need to evaluate the realm on a request basis. During the authentication and authorization phase of the incoming request, Keycloak queries the application via this extension point and expects the application to return a complete representation of the realm. With this, Keycloak then proceeds the authentication and authorization process, accepting or refusing the request based on the incoming credentials and on the returned realm. For this scenario, an application needs to:

  • Add a context parameter to the web.xml, named keycloak.config.resolver. The value of this property should be the fully qualified name of the class extending org.keycloak.adapters.KeycloakConfigResolver.
  • A concrete implementation of org.keycloak.adapters.KeycloakConfigResolver. Keycloak will call the resolve(org.keycloak.adapters.HttpFacade.Request) method and expects a complete org.keycloak.adapters.KeycloakDeployment in response. Note that Keycloak will call this for every request, so, take the usual performance precautions.

An implementation of this feature can be found in the examples.

It's generally not needed to use JAAS for most of the applications, especially if they are HTTP based, but directly choose one of our adapters. However some applications and systems may still rely on pure legacy JAAS solution. Keycloak provides couple of login modules to help with such use cases. Some login modules provided by Keycloak are:

org.keycloak.adapters.jaas.DirectAccessGrantsLoginModule

This login module allows to authenticate with username/password from Keycloak database. It's using Direct Access Grants Keycloak endpoint to validate on Keycloak side if provided username/password is valid. It's useful especially for non-web based systems, which need to rely on JAAS and want to use Keycloak credentials, but can't use classic browser based authentication flow due to their non-web nature. Example of such application could be messaging application or SSH system.

org.keycloak.adapters.jaas.BearerTokenLoginModule

This login module allows to authenticate with Keycloak access token passed to it through CallbackHandler as password. It may be useful for example in case, when you have Keycloak access token from classic web based authentication flow and your web application then needs to talk to external non-web based system, which rely on JAAS. For example to JMS/messaging system.

Both login modules have configuration property keycloak-config-file where you need to provide location of keycloak.json configuration file. It could be either provided from filesystem or from classpath (in that case you may need value like classpath:/folder-on-classpath/keycloak.json ).

Second property role-principal-class allows to specify alternative class for Role principals attached to JAAS Subject. Default value for Role principal is org.keycloak.adapters.jaas.RolePrincipal . Note that class should have constructor with single String argument.

An Identity Broker is an intermediary service that connects multiple service providers with different identity providers. As an intermediary service, the identity broker is responsible to create a trust relationship with an external identity provider in order to use its identities to access internal services exposed by service providers.

From an user perspective, an identity broker provides an user-centric and centralized way to manage identities across different security domains or realms, where an existing account can be linked with one or more identities from different identity providers or even created based on the identity information obtained from them.

An identity provider is usually based on a specific protocol in order to authenticate and communicate authentication and authorization information to their users. It can be a social provider such as Facebook, Google or Twitter, a business partner which you want to allow its users to access your services or a cloud-based identity service that you want to integrate with. Usually, identity providers are based on the following protocols:

  • SAML v2.0

  • OpenID Connect v1.0

  • oAuth v2.0

In the next sections we'll see how to configure and use Keycloak as an identity broker, covering some important aspects such as:

  • Social Authentication

  • OpenID Connect v1.0 Brokering

  • SAML v2.0 Brokering

  • Identity Federation

When using Keycloak as an identity broker, users are not forced to provide their credentials in order to authenticate in a specific realm. Instead of that, they are presented with a list of identity providers from where they can pick one and authenticate. You can also configure a hard-coded default broker. In this case the user will not be given a choice, but instead be redirected directly the the parent broker. The following diagram demonstrates the steps involved when using Keycloak to broker an external identity provider:

  1. User is not authenticated and requests a protected resource in a service provider.

  2. The service provider redirects the user to Keycloak to authenticate.

  3. At this point the user is presented to the login page where there is a list of identity providers supported by a realm.

  4. User selects one of the identity providers by clicking on its respective button or link.

  5. Keycloak issues an authentication request to the target identity provider asking for authentication and the user is redirect to the login page or just to a consent page in the identity provider. The connection properties and other configuration options for the identity provider were previously set by the administrator in the admin console.

  6. User provides his credentials or consent in order to authenticate in the identity provider.

  7. Upon a successful authentication by the identity provider, the user is redirected back to Keycloak with an authentication response. Usually this response contains a security token that will be used by Keycloak to trust the authentication performed by the identity provider and retrieve information about the user.

  8. Now Keycloak is going to check if the response from the identity provider is valid. If valid, it will create an user or just skip that if the user already exists. If it is a new user, Keycloak will ask informations about the user to the identity provider (or just read that from a security token) and create the user locally. This is what we call identity federation. If the user already exists Keycloak will ask him to link the identity returned from the identity provider with his existing account. A process that we call account linking. At the end of this step, Keycloak authenticates the user and issues its own token in order to access the requested resource in the service provider.

  9. Once the user is locally authenticated, Keycloak redirects the user to the service provider by sending the token previously issued during the local authentication.

  10. The service provider receives the token from Keycloak and allows access to the protected resource.

There are some variations of this flow that we will talk about later. For instance, instead of present a list of identity providers, the service provider can automatically select a specific one to authenticate an user. Or you can tell Keycloak to force the user to provide additional information before federate his identity.

Note

Different protocols may require different authentication flows. At this moment, all the identity providers supported by KeyCloak use a flow just like described above. However, despite the protocol in use, user experience should be pretty much the same.

As you may notice, at the end of the authentication process Keycloak will always issue its own token to service providers, what means that service providers are completely decoupled from external identity providers. They don't need to know which protocol (eg.: SAML, OpenID Connect, oAuth, etc) was used or how the user's identity was validated. They only need to know about Keycloak !

The identity broker configuration is all based on identity providers. Identity providers are created for each realm and by default they are enabled for every single application. That means that users from a realm can use any of the registered identity providers when signing in to an application.

In order to create an identity provider, follow these steps:

  1. In the admin console, select a realm.

  2. On the left side menu, click on Settings.

  3. Select the Identity Provider tab on the settings page.

  4. You should now be able to see a table that lists all registered identity providers. To add a new identity provider, click the select box on the top right of this table and select which type of identity provider you want to create.

Identity providers are organized in two main categories:

Social

Social providers allows you to enable social authentication to your realm. Keycloak makes it easy to let users log in to your application using an existing account with a social network. Currently Facebook, Google and Twitter are supported with more planned for the future.

Protocol-based

Protocol-based providers are those that rely on a specific protocol in order to authenticate and authorize users. They allow you to connect to any identity provider compliant with a specific protocol. Keycloak provides support for SAML v2.0 and OpenID Connect v1.0 protocols. It makes it easy to configure and broker any identity provider based on these open standards.

Although each type of identity provider has its own configuration options, all of them share some very common configuration. Regardless the identity provider you are creating, you'll see the following configuration options avaiable:

Table 9.1. Common Configuration

Configuration Description
Alias The alias is an unique identifier for an identity provider. It is used to reference internally an identity provider. Some protocols require a redirect uri or callback url in order to communicate with an identity provider. For instance, OpenID Connect. In this case, the alias is used to build the redirect uri. Every single identity provider must have an alias. For example, facebook, google, idp.acme.com, etc.
Name You can give a friendly name to an identity provider. The name will be used, for example, to display a link or a button in the login page.
Enabled Allows you to enable or disable an identity provider. When disabled, the identity provider will not be available from the login page and can not be used by any other means.
Store Tokens Any external tokens provided by the parent IDP will be stored. This options is useful if you are using social authentication and need to access the token in order to invoke the API of a social provider on behalf of the user.
Stored Tokens Readable Automatically assigns a broker.read-token role that allows the user to access any stored external tokens via the broker service.
Update Profile on First Login Allows you to force users to update their profile right after the authentication finishes and before the account is actually created in Keycloak. When enabled, users will be presented with the update profile page asking for additional information in order to federate their identities. If disabled, the account will be created with the minimal information obtained from the identity provider during the authentication process.
GUI order Allows you to define order of the provider when shown on login page. You can put number into this field, providers with lower numbers are shown first.

On the next sections, we'll see how to configure each type of identity provider individually.

Forcing users to register to your realm when they want to access applications is hard. So is trying to remember yet another username and password combination. Social identity providers makes it easy for users to register on your realm and quickly sign in using a social network. Keycloak provides built-in support for the most common social networks out there, such as Google, Facebook, Twitter and even Github.

To enable login with Google you first have to create a project and a client in the Google Developer Console. Then you need to copy the client id and secret into the Keycloak Admin Console.

Let's see first how to create a project with Google.

  1. Log in to the Google Developer Console. Click the Create Project button. Use any value for Project name and Project ID you want, then click the Create button. Wait for the project to be created (this may take a while).

  2. Once the project has been created click on APIs & auth in sidebar on the left. To retrieve user profiles the Google+ API has to be enabled. Scroll down to find it in the list. If its status is OFF, click on OFF to enable it (it should move to the top of the list and the status should be ON).

  3. Now click on the Consent screen link on the sidebar menu on the left. You must specify a project name and choose an email for the consent screen. Otherwise users will get a login error. There's other things you can configure here like what the consent screen looks like. Feel free to play around with this.

  4. Now click Credentials in the sidebar on the left. Then click Create New Client ID. Select Web application as Application type. Empty the Authorized Javascript origins textarea. Click the Create Client ID button.

  5. Copy Client ID and Client secret.

Now that you have the client id and secret, you can proceed with the creation of a Google Identity Provider in Keycloak. As follows:

  1. Select the Google identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provided.

  2. Copy the client id and secret to their corresponding fields in the Keycloak Admin Console. Click Save.

Once you create the identity provider in Keycloak, you must update your Google project with the redirect url that was generated to your identity provider.

  1. Open the Google Developer Console and select your project. Click Credentials in the sidebar on the left. In Authorized redirect URI insert the redirect uri created by Keycloak. The redirect uri usually have the following format: http://{host}:{port}/auth/realms/{realm}/broker/{provider_alias}.

Note

You can always get the redirect url for a specific identity provider from the table presented when you click on the 'Identity Provider' tab in Realm > Settings.

That is it! This is pretty much what you need to do in order to setup this identity provider.

The table below lists some additional configuration options you may use when configuring this provider.


To enable login with Facebook you first have to create an application in the Facebook Developer Console. Then you need to copy the client id and secret into the Keycloak Admin Console.

Let's see first how to create an application with Facebook.

  1. Log in to the Facebook Developer Console. Click Apps in the menu and select Create a New App. Use any value for Display Name and Category you want, then click the Create App button. Wait for the project to be created (this may take a while). If after creating the app you are not redirected to the app settings, click on Apps in the menu and select the app you created.

  2. Once the app has been created click on Settings in sidebar on the left. You must specify a contact email. Save your changes. Then click on Advanced. Under Security make sure Client OAuth Login is enabled. Scroll down and click on the Save Changes button.

  3. Click Status & Review and select YES for Do you want to make this app and all its live features available to the general public?. You will not be able to set this until you have provided a contact email in the general settings of this application.

  4. Click Basic. Copy App ID and App Secret (click show) from the Facebook Developer Console.

Now that you have the client id and secret, you can proceed with the creation of a Facebook Identity Provider in Keycloak. As follows:

  1. Select the Facebook identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provided.

  2. Copy the client id and secret to their corresponding fields in the Keycloak Admin Console. Click Save.

Once you create the identity provider in Keycloak, you must update your Facebook application with the redirect url that was generated to your identity provider.

  1. Open the Facebook Developer Console and select your application. Click on Advanced. Under Security make sure Client OAuth Login is enabled. In Valid OAuth redirect URIs insert the redirect uri created by Keycloak. The redirect uri usually have the following format: http://{host}:{port}/auth/realms/{realm}/broker/{provider_alias}.

Note

You can always get the redirect url for a specific identity provider from the table presented when you click on the 'Identity Provider' tab in Realm > Settings.

That is it! This pretty much what you need to do in order to setup this identity provider.

The table below lists some additional configuration options you may use when configuring this provider.


To enable login with Twtter you first have to create an application in the Twitter Developer Console. Then you need to copy the consumer key and secret into the Keycloak Admin Console.

Let's see first how to create an application with Twitter.

  1. Log in to the Twitter Developer Console. Click the Create a new application button. Use any value for Name, Description and Website you want. Insert the social callback url in Callback URL. Then click Create your Twitter application.

  2. Now click on Settings and tick the box Allow this application to be used to Sign in with Twitter, then click on Update this Twitter application's settings.

  3. Now click API Keys tab. Copy API key and API secret from the Twitter Developer Console.

Note

Twitter doesn't allow localhost in the redirect URI. To test on a local server replace localhost with 127.0.0.1.

Now that you have the client id and secret, you can proceed with the creation of a Twitter Identity Provider in Keycloak. As follows:

  1. Select the Twitter identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provided.

  2. Copy the client id and secret to their corresponding fields in the Keycloak Admin Console. Click Save.

That is it! This pretty much what you need to do in order to setup this identity provider.

The table below lists some additional configuration options you may use when configuring this provider.


To enable login with GitHub you first have to create an application in GitHub Settings. Then you need to copy the client id and secret into the Keycloak Admin Console.

Let's see first how to create an application with GitHub.

  1. Log in to GitHub Settings. Click the Register new application button. Use any value for Application name, Homepage URL and Application Description you want. Click the Register application button.

  2. Copy Client ID and Client Secret from the GitHub Settings.

Now that you have the client id and secret, you can proceed with the creation of a Github Identity Provider in Keycloak. As follows:

  1. Select the Github identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provided.

  2. Copy the client id and secret to their corresponding fields in the Keycloak Admin Console. Click Save.

Once you create the identity provider in Keycloak, you must update your GitHub application with the redirect url that was generated to your identity provider.

  1. Open the GitHub Settings and select your application. In Authorization callback URL insert the redirect uri created by Keycloak. The redirect uri usually have the following format: http://{host}:{port}/auth/realms/{realm}/broker/{provider_alias}.

Note

You can always get the redirect url for a specific identity provider from the table presented when you click on the 'Identity Provider' tab in Realm > Settings.

That is it! This pretty much what you need to do in order to setup this identity provider.

The table below lists some additional configuration options you may use when configuring this provider.


To enable login with LinkedIn you first have to create an application in LinkedIn Developer Network. Then you need to copy the client id and secret into the Keycloak Admin Console.

Let's see first how to create an application with LinkedIn.

  1. Log in to LinkedIn Developer Network. Click the Add New Application link. Use any value for Application Name, Website URL, Description, Developer Contact Email and Phone you want. Select r_basicprofile and r_emailaddress in the Default Scope section. Click the Add Application button.

  2. Copy Consumer Key / API Key and Consumer Secret / Secret Key from the shown page.

Now that you have the client id and secret, you can proceed with the creation of a LinkedIn Identity Provider in Keycloak. As follows:

  1. Select the LinkedIn identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provided.

  2. Copy the client id and secret to their corresponding fields in the Keycloak Admin Console. Click Save.

Once you create the identity provider in Keycloak, you must update your LinkedIn application with the redirect url that was generated to your identity provider.

  1. Open the LinkedIn Developer Network and select your application. In OAuth 2.0 Redirect URLs insert the redirect uri created by Keycloak. The redirect uri usually have the following format: http://{host}:{port}/auth/realms/{realm}/broker/{provider_alias}/endpoint.

Note

You can always get the redirect url for a specific identity provider from the table presented when you click on the 'Identity Provider' tab in Realm > Settings.

That is it! This pretty much what you need to do in order to setup this identity provider.

The table below lists some additional configuration options you may use when configuring this provider.


To enable login with StackOverflow you first have to register an OAuth application on StackApps. Then you need to copy the client id, secret and key into the Keycloak Admin Console.

Let's see first how to create an application with StackOverflow.

  1. Go to registering your application on Stack Apps url and login here. Use any value for Application Name, Application Website and Description you want. Set OAuth Domain to the domain where your Keycloak instance runs. Click the Register Your Application button.

  2. Copy Client Id, Client Secret and Key from the shown page.

Now that you have the client id, secret and key, you can proceed with the creation of a StackOverflow Identity Provider in Keycloak. As follows:

  1. Select the StackOverflow identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provided.

  2. Copy the client id, client secret and key to their corresponding fields in the Keycloak Admin Console. Click Save.

That is it! This pretty much what you need to do in order to setup this identity provider.

The table below lists some additional configuration options you may use when configuring this provider.


Keycloak can broker identity providers based on the SAML v2.0 protocol.

In order to configure a SAML identity provider, follow these steps:

  1. Select the SAML v2.0 identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provider.

When configuring a SAML identity provider you are presented with different configuration options in order to properly communicate and integrate with the external identity provider. In this case, you must keep in mind that Keycloak will act as an Service Provider that issues authentication requests(AuthnRequest) to the external identity provider.

Table 9.8. Configuration Options

Configuration Description
Import IdP SAML Metadata When creating a new identity provider, you may just upload the SAML Metadata for the brokered IdP (IDPSSODescriptor). In this case, Keycloak will read all the necessary configuration from the metadata and automatically configure the identity provider for you.
Single Sign-On Service Url Allows you to specify the URL that will be used to send SAML authentication requests.
Single Logout Service Url Allows you to specify the URL that will be used to send SAML logout requests.
Backchannel Logout If set to true, logout to the external IDP will be done in a background HTTP request. If set to false, then the browser will be redirected to the external IDP to perform the logout.
NameID Policy Format Allows you to specify a NameID Policy that will be sent in the SAML authentication request.
Validating X509 Certificate Allows you to specify the certificate in PEM format that will be used to validate signatures for all messages received from the brokered identity provider.
Want AuthnRequests Signed Allows you to specify whether the brokered identity provider is expecting signed SAML authentication requests or not.
Force Authentication Allows you to tell the brokered identity provider that user must be authenticated even if he was previously authenticated (re-authentication) in the same session.
Validate Signature Enable or disable signature validation of any message returned by the brokered identity provider.
HTTP-POST Binding Response Allows you to specify if responses from the brokered identity providers are returned using the HTTP-POST or HTTP-Redirect protocol bindings. If enabled, only responses using HTTP-POST binding are accepted.
HTTP-POST Binding for AuthnReques Allows you to specify wheter SAML authentication requests must be sent using the HTTP-POST or HTTP-Redirect protocol bindings. If enabled, it will send requests using HTTP-POST binding.

You can also import all this configuration data by providing a URL or XML file that points to the entity descriptor of the external SAML IDP you want to connect to.

Once you create a SAML provider, there is an EXPORT button that appears when viewing that provider. Clicking this button will export a SAML entity descriptor which you can use to

Keycloak can broker identity providers based on the OpenID Connect v1.0 protocol.

In order to configure a OIDC identity provider, follow these steps:

  1. Select the OpenID Connect v1.0 identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provider.

When configuring an OIDC identity provider you are presented with different configuration options in order to send authentication requests to the external identity provider. In this case, the brokered identity provider must support the Authorization Code Flow (as defined by the specification) in order to authenticate the user and authorize access for the scopes specified in the configuration.


You can also import all this configuration data by providing a URL or file that points to OpenID Provider Metadata (see OIDC Discovery specification)

Keycloak provides theme support for web pages and emails. This allows customizing the look and feel of end-user facing pages so they can be integrated with your applications.

A theme consists of:

  • FreeMarker templates
  • Stylesheets
  • Scripts
  • Images
  • Message bundles
  • Theme properties

A theme can extend another theme. When extending a theme you can override individual files (templates, stylesheets, etc.). The recommended way to create a theme is to extend the base theme. The base theme provides templates and a default message bundle. If you decide to override templates bear in mind that you may need to update your templates when upgrading to a new release to include any changes made to the original template.

Before creating a theme it's a good idea to disable caching as this makes it possible to edit theme resources without restarting the server. To do this open ../standalone/configuration/keycloak-server.json for theme set staticMaxAge to -1 and cacheTemplates and cacheThemes to false. For example:

[
"theme": {
    "default": "keycloak",
    "staticMaxAge": -1,
    "cacheTemplates": false,
    "cacheThemes": false,
    "folder": {
      "dir": "${jboss.server.config.dir}/themes"
    }
},

Remember to re-enable caching in production as it will significantly impact performance.

To create a new theme create a directory for the theme in .../standalone/configuration/themes. The name of the directory should be the name of the theme. For example to create a theme called example-theme create the directory .../standalone/configuration/themes/example-theme. Inside the theme directory you then need to create a directory for each of the types your theme is going to provide. For example to add the login type to the example-theme theme create the directory .../standalone/configuration/themes/example-theme/login.

For each type create a file theme.properties which allows setting some configuration for the theme, for example what theme it overrides and if it should import any themes. For the above example we want to override the base theme and import common resources from the Keycloak theme. To do this create the file .../standalone/configuration/themes/example-theme/login/theme.properties with the following contents:

[
parent=base
import=common/keycloak

You have now created a theme with support for the login type. To check that it works open the admin console. Select your realm and click on Themes. For Login Theme select example-theme and click Save. Then open the login page for the realm. You can do this either by login through your application or by opening http://localhost:8080/realms/<realm name>/account.

To see the effect of changing the parent theme, set parent=keycloak in theme.properties and refresh the login page. To follow the rest of the documentation set it back to parent=base before continuing.

Keycloak uses Freemarker Templates in order to generate HTML. These templates are defined in .ftl files and can be overriden from the base theme. Check out the Freemarker website on how to form a template file. To override the login template for the example-theme copy ../standalone/configuration/themes/base/login/login.ftl to ../standalone/configuration/themes/example-theme/login and open it in an editor. After the first line (<#import ...>) add <h1>HELLO WORLD!</h1> then refresh the page.

Themes can be deployed to Keycloak by copying the theme directory to ../standalone/configuration/themes or it can be deployed as a module. For a single server or during development just copying the theme is fine, but in a cluster or domain it's recommended to deploy as a module.

To deploy a theme as a module you need to create an jar (it's basically just a zip with jar extension) with the theme resources and a file META/keycloak-themes.json that describes the themes contained in the archive. For example example-theme.jar with the contents:

  • META-INF/keycloak-themes.json
  • theme/example-theme/login/theme.properties
  • theme/example-theme/login/login.ftl
  • theme/example-theme/login/resources/css/styles.css

The contents of META-INF/keycloak-themes.json in this case would be:

[
{
    "themes": [{
        "name" : "example-theme",
        "types": [ "login" ]
    }]
}

As you can see a single jar can contain multiple themes and each theme can support one or more types.

The deploy the jar as a module to Keycloak you can either manually create the module or use jboss-cli. It's simplest to use jboss-cli as it creates the required directories and module descriptor for you. To deploy the above jar jboss-cli run:

[
    KEYCLOAK_HOME/bin/jboss-cli.sh --command="module add --name=org.example.exampletheme --resources=example-theme.jar"

If you're on windows run

KEYCLOAK_HOME/bin/jboss-cli.bat

.

This command creates modules/org/example/exampletheme/main containing example-theme.jar and module.xml.

Once you've created the module you need to register it with Keycloak do this by editing ../standalone/configuration/keycloak-server.json and adding the module to theme/module/modules. For example:

[
"theme": {
    ...
    "module": {
        "modules": [ "org.example.exampletheme" ]
    }
}

If a theme is deployed to ../standalone/configuration/themes and as a module the first is used.

Keycloak sends emails to users to verify their email address. Emails are also used to allow users to safely restore their username and passwords.

When you create a Client in admin console you may be wondering what the "Access Types" are.

confidential

Confidential access type is for clients that need to perform a browser login and that you want to require a client secret when they turn an access code into an access token, (see Access Token Request in the OAuth 2.0 spec for more details). The advantages of this is that it is a little extra security. Since Keycloak requires you to register valid redirect-uris, I'm not exactly sure what this little extra security is though. :) The disadvantages of this access type is that confidential access type is pointless for pure Javascript clients as anybody could easily figure out your client's secret!

public

Public access type is for clients that need to perform a browser login and that you feel that the added extra security of confidential access type is not needed. FYI, Pure javascript clients are by nature public.

bearer-only

Bearer-only access type means that the application only allows bearer token requests. If this is turned on, this application cannot participate in browser logins.

direct access only

You would also see a "Direct Access Only" switch when creating the Client. This switch is for clients that only use the Direct Access Grant protocol to obtain access tokens.

In Keycloak, roles (or permissions) can be defined globally at the realm level, or individually per application. Each role has a name which must be unique at the level it is defined in, i.e. you can have only one "admin" role at the realm level. You may have that a role named "admin" within an Application too, but "admin" must be unique for that application.

The description of a role is displayed in the OAuth Grant page when Keycloak is processing a browser OAuth Grant request. Look for more features being added here in the future like internationalization and other fine grain options.

Keycloak allows you to make direct REST invocations to obtain an access token. (See Resource Owner Password Credentials Grant from OAuth 2.0 spec). To use it, Direct Access Grants must be allowed by your realm. This is a configuration switch in the admin console under Settings->General, specifically the "Direct Grant API" switch. You must also have registered a valid Client to use as the "client_id" for this grant request.

Warning

It is highly recommended that you do not use Direct Access Grants to write your own login pages for your application. You will lose a lot of features that Keycloak has if you do this. Specifically all the account management, remember me, lost password, account reset features of Keycloak. Instead, if you want to tailor the look and feel of Keycloak login pages, you should create your own theme.

It is even highly recommended that you use the browser to log in for native mobile applications! Android and iPhone applications allow you to redirect to and from the browser. You can use this to redirect the user from your native mobile app to the web browser to perform login, then the browser will redirect back to your native application.

The REST URL to invoke on is /{keycloak-root}/realms/{realm-name}/protocol/openid-connect/token. Invoking on this URL is a POST request and requires you to post the username and credentials of the user you want an access token for. You must also pass along the "client_id" of the client you are creating an access token for. This "client_id" is the Client Id specified in admin console (not it's id from DB!). Depending on whether your client is "public" or "confidential", you may also have to pass along it's client secret as well. Finally you need to pass "grant_type" parameter with value "password" .

For public client's, the POST invocation requires form parameters that contain the username, credentials, and client_id of your application. For example:

    POST /auth/realms/demo/protocol/openid-connect/token
    Content-Type: application/x-www-form-urlencoded

    username=bburke&password=geheim&client_id=customer-portal&grant_type=password

The response would be this standard JSON document from the OAuth 2.0 specification.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "token_type":"bearer",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
    "id_token":"tGzv3JOkF0XG5Qx2TlKWIA",
    "session-state":"234234-234234-234234"
}

For confidential client's, you must create a Basic Auth Authorization header that contains the client_id and client secret. And pass in the form parameters for username and for each user credential. For example:

    POST /auth/realms/demo/protocol/openid-connect/token
    Authorization: Basic atasdf023l2312023
    Content-Type: application/x-www-form-urlencoded

    username=bburke&password=geheim&grant_type=password

Here's a Java example using Apache HTTP Client and some Keycloak utility classes.:

HttpClient client = new HttpClientBuilder()
                .disableTrustManager().build();


try {
   HttpPost post = new HttpPost(
           KeycloakUriBuilder.fromUri("http://localhost:8080/auth")
           .path(ServiceUrlConstants.TOKEN_PATH).build("demo"));
   List <NameValuePair> formparams = new ArrayList <NameValuePair>();
   formparams.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, "password"));
   formparams.add(new BasicNameValuePair("username", "bburke"));
   formparams.add(new BasicNameValuePair("password", "password"));

   if (isPublic()) { // if client is public access type
       formparams.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, "customer-portal"));
   } else {
       String authorization = BasicAuthHelper.createHeader("customer-portal", "secret-secret-secret");
       post.setHeader("Authorization", authorization);
   }
   UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8");
   post.setEntity(form);

   HttpResponse response = client.execute(post);
   int status = response.getStatusLine().getStatusCode();
   HttpEntity entity = response.getEntity();
   if (status != 200) {
      throw new IOException("Bad status: " + status);
   }
   if (entity == null) {
      throw new IOException("No Entity");
   }
   InputStream is = entity.getContent();
   try {
      AccessTokenResponse tokenResponse = JsonSerialization.readValue(is, AccessTokenResponse.class);
   } finally {
      try {
          is.close();
      } catch (IOException ignored) { }
      }
} finally {
   client.getConnectionManager().shutdown();
}


Once you have the access token string, you can use it in REST HTTP bearer token authorized requests, i.e

GET /my/rest/api
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA

To logout you must use the refresh token contained in the AccessTokenResponse object.

    
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
if (isPublic()) { // if client is public access type
    formparams.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, "customer-portal"));
} else {
    String authorization = BasicAuthHelper.createHeader("customer-portal", "secret-secret-secret");
    post.setHeader("Authorization", authorization);
}
formparams.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, tokenResponse.getRefreshToken()));
HttpResponse response = null;
URI logoutUri = KeycloakUriBuilder.fromUri(getBaseUrl(request) + "/auth")
                    .path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
                    .build("demo");
HttpPost post = new HttpPost(logoutUri);
UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8");
post.setEntity(form);
response = client.execute(post);
int status = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
if (status != 204) {
   error(status, entity);
}
if (entity == null) {
   return;
}
InputStream is = entity.getContent();
if (is != null) is.close();

CORS stands for Cross-Origin Resource Sharing. If executing browser Javascript tries to make an AJAX HTTP request to a server's whose domain is different than the one the Javascript code came from, then the request uses the CORS protocol. The server must handle CORS requests in a special way, otherwise the browser will not display or allow the request to be processed. This protocol exists to protect against XSS and other Javascript-based attacks. Keycloak has support for validated CORS requests.

Keycloak's CORS support is configured per client. You specify the allowed origins in the client's configuration page in the admin console. You can add as many you want. The value must be what the browser would send as a value in the Origin header. For example http://example.com is what you must specify to allow CORS requests from example.com. When an access token is created for the client, these allowed origins are embedded within the token. On authenticated CORS requests, your application's Keycloak adapter will handle the CORS protocol and validate the Origin header against the allowed origins embedded in the token. If there is no match, then the request is denied.

To enable CORS processing in your application's server, you must set the enable-cors setting to true in your adapter's configuration file. When this setting is enabled, the Keycloak adapter will handle all CORS preflight requests. It will validate authenticated requests (protected resource requests), but will let unauthenticated requests (unprotected resource requests) pass through.

Keycloak has a bunch of fine-grain settings to manage browser cookies, user login sessions, and token lifespans. Sessions can be viewed and managed within the admin console for all users, and individually in the user's account management pages. This chapter goes over configuration options for cookies, sessions, and tokens.

The Keycloak Admin Console is implemented entirely with a fully functional REST admin API. You can invoke this REST API from your Java applications by obtaining an access token. You must have the appropriate permissions set up as described in Chapter 6, Master Admin Access Control and Chapter 7, Per Realm Admin Access Control

The documentation for this REST API is auto-generated and is contained in the distribution of keycloak under the docs/rest-api/overview-index.html directory, or directly from the docs page at the keycloak website.

There are a number of examples that come with the keycloak distribution that show you how to invoke on this REST API. examples/preconfigured-demo/admin-access-app shows you how to access this api from java. examples/cors/angular-product-app shows you how to invoke on it from Javascript. Finally there is example in example/admin-client, which contains example for Admin client, that can be used to invoke REST endpoints easily as Java methods.

Keycloak provides an Events SPI that makes it possible to register listeners for user related events, for example user logins. There are two interfaces that can be implemented, the first is a pure listener, the second is a events store which listens for events, but is also required to store events. An events store provides a way for the admin and account management consoles to view events.

Keycloak can federate external user databases. Out of the box we have support for LDAP and Active Directory. Before you dive into this, you should understand how Keycloak does federation.

Keycloak performs federation a bit differently than other products/projects. The vision of Keycloak is that it is an out of the box solution that should provide a core set of feature irregardless of the backend user storage you want to use. Because of this requirement/vision, Keycloak has a set data model that all of its services use. Most of the time when you want to federate an external user store, much of the metadata that would be needed to provide this complete feature set does not exist in that external store. For example your LDAP server may only provide password validation, but not support TOTP or user role mappings. The Keycloak User Federation SPI was written to support these completely variable configurations.

The way user federation works is that Keycloak will import your federated users on demand to its local storage. How much metadata that is imported depends on the underlying federation plugin and how that plugin is configured. Some federation plugins may only import the username into Keycloak storage, others might import everything from name, address, and phone number, to user role mappings. Some plugins might want to import credentials directly into Keycloak storage and let Keycloak handle credential validation. Others might want to handle credential validation themselves. The goal of the Federation SPI is to support all of these scenarios.

Keycloak comes with a built-in LDAP/AD plugin. Currently it is set up only to import username, email, first and last name. It supports password validation via LDAP/AD protocols and different user metadata synchronization modes. To configure a federated LDAP store go to the admin console. Click on the Users menu option to get you to the user management page. Then click on the Federation submenu option. When you get to this page there is an "Add Provider" select box. You should see "ldap" within this list. Selecting "ldap" will bring you to the ldap configuration page.

LDAP Federation Provider will automatically take care of synchronization (import) of needed LDAP users into Keycloak database. For example once you first authenticate LDAP user john from Keycloak UI, LDAP Federation provider will first import this LDAP user into Keycloak database and then authenticate against LDAP password.

Federation Provider imports just requested users by default, so if you click to View all users in Keycloak admin console, you will see just those LDAP users, which were already authenticated/requested by Keycloak.

If you want to sync all LDAP users into Keycloak database, you may configure and enable Sync, which is in admin console on same page like the configuration of Federation provider itself. There are 2 types of sync:

Full sync

This will synchronize all LDAP users into Keycloak DB. Those LDAP users, which already exist in Keycloak and were changed in LDAP directly will be updated in Keycloak DB (For example if user Mary Kelly was changed in LDAP to Mary Doe).

Changed users sync

This will check LDAP and it will sync into Keycloak just those users, which were created or updated in LDAP from the time of last sync.

In usual cases you may want to trigger full sync at the beginning, so you will import all LDAP users to Keycloak just once. Then you may setup periodic sync of changed users, so Keycloak will periodically ask LDAP server for newly created or updated users and backport them to Keycloak DB. Also you may want to trigger full sync again after some longer time or setup periodic full sync as well.

In admin console, you can trigger sync directly or you can enable periodic changed or full sync.

The keycloak examples directory contains an example of a simple User Federation Provider backed by a simple properties file. See examples/providers/federation-provider. Most of how to create a federation provider is explained directly within the example code, but some information is here too.

Writing a User Federation Provider starts by implementing the UserFederationProvider and UserFederationProviderFactory interfaces. Please see the Javadoc and example for complete details on how to do this. Some important methods of note: getUserByUsername() and getUserByEmail() require that you query your federated storage and if the user exists create and import the user into Keycloak storage. How much metadata you import is fully up to you. This import is done by invoking methods on the object returned KeycloakSession.userStorage() to add and import user information. The proxy() method will be called whenever Keycloak has found an imported UserModel. This allows the federation provider to proxy the UserModel which is useful if you want to support external storage updates on demand.

After your code is written you must package up all your classes within a JAR file. This jar file must contain a file called org.keycloak.models.UserFederationProviderFactory within the META-INF/services directory of the JAR. This file is a list of fully qualified classnames of all implementations of UserFederationProviderFactory. For more details on writing provider implementations and how to deploy to Keycloak refer to the providers section.

Keycloak supports login with Kerberos ticket through SPNEGO. SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) is used to authenticate transparently through the web browser after the user has been authenticated when logging-in his session. For non-web cases or when ticket is not available during login, Keycloak also supports login with Kerberos username/password.

A typical use case for web authentication is the following:

  1. User logs into his desktop (Such as a Windows machine in Active Directory domain or Linux machine with Kerberos integration enabled).

  2. User then uses his browser (IE/Firefox/Chrome) to access a web application secured by Keycloak.

  3. Application redirects to Keycloak login.

  4. Keycloak sends HTML login screen together with status 401 and HTTP header WWW-Authenticate: Negotiate

  5. In case that browser has Kerberos ticket from desktop login, it transfers the desktop sign on information to the Keycloak in header Authorization: Negotiate 'spnego-token' . Otherwise it just displays login screen.

  6. Keycloak validates token from browser and authenticate user. It provisions user data from LDAP (in case of LDAPFederationProvider with Kerberos authentication support) or let user to update his profile and prefill data (in case of KerberosFederationProvider).

  7. Keycloak returns back to the application. Communication between Keycloak and application happens through OpenID Connect or SAML messages. The fact that Keycloak was authenticated through Kerberos is hidden from the application. So Keycloak acts as broker to Kerberos/SPNEGO login.

For setup there are 3 main parts:

  1. Setup and configuration of Kerberos server (KDC)

  2. Setup and configuration of Keycloak server

  3. Setup and configuration of client machines

Clients need to install kerberos client and setup krb5.conf as described above. Additionally they need to enable SPNEGO login support in their browser. See for example this for more info about Firefox. URI .mydomain.org must be allowed in network.negotiate-auth.trusted-uris config option.

In windows domain, clients usually don't need to configure anything special as IE is already able to participate in SPNEGO authentication for the windows domain.

For easier testing with Kerberos, we provided some example setups to test.

Once you install docker, you can run docker image with FreeIPA server installed. FreeIPA provides integrated security solution with MIT Kerberos and 389 LDAP server among other things . The image provides also Keycloak server configured with LDAP Federation provider and enabled SPNEGO/Kerberos authentication against the FreeIPA server. See details here .

For quick testing and unit tests, we use very simple ApacheDS Kerberos server. You need to build Keycloak from sources and then run Kerberos server with maven-exec-plugin from our testsuite. See details here .

One scenario supported by Kerberos 5 is credential delegation. In this case when user receives forwardable TGT and authenticates to the web server, then web server might be able to reuse the ticket and forward it to another service secured by Kerberos (for example LDAP server or IMAP server).

The scenario is supported by Keycloak, but there is tricky thing that SPNEGO authentication is done by Keycloak server but GSS credential will need to be used by your application. So you need to enable built-in gss delegation credential protocol mapper in admin console for your application. This will cause that Keycloak will deserialize GSS credential and transmit it to the application in access token. Application will need to deserialize it and use it for further GSS calls against other services. We have an example, which is showing it in details. It's in examples/kerberos in the Keycloak appliance distribution or WAR distribution download. You can also check the example sources directly here .

Once you deserialize the credential from the access token to the GSSCredential object, then GSSContext will need to be created with this credential passed to the method GSSManager.createContext for example like this:

GSSContext context = gssManager.createContext(serviceName, krb5Oid,
    deserializedGssCredFromKeycloakAccessToken, GSSContext.DEFAULT_LIFETIME);

Note that you also need to configure forwardable kerberos tickets in krb5.conf file and add support for delegated credentials to your browser. For details, see the kerberos example from Keycloak examples set as mentioned above.

Warning

Credential delegation has some security implications. So enable the protocol claim and support in browser just if you really need it. It's highly recommended to use it together with HTTPS. See for example this article for details.

Export/import is useful especially if you want to migrate your whole Keycloak database from one environment to another or migrate to different database (For example from MySQL to Oracle). You can trigger export/import at startup of Keycloak server and it's configurable with System properties right now. The fact it's done at server startup means that no-one can access Keycloak UI or REST endpoints and edit Keycloak database on the fly when export or import is in progress. Otherwise it could lead to inconsistent results.

You can export/import your database either to:

  • Encrypted ZIP file on local filesystem
  • Directory on local filesystem
  • Single JSON file on your filesystem

When importing using the "dir" or "zip" strategies, note that the files need to follow the naming convention specified below. If you are importing files which were previously exported, the files already follow this convention.

  • {REALM_NAME}-realm.json, such as "acme-roadrunner-affairs-realm.json" for the realm named "acme-roadrunner-affairs"
  • {REALM_NAME}-users-{INDEX}.json, such as "acme-roadrunner-affairs-users-0.json" for the first users file of the realm named "acme-roadrunner-affairs"

Encrypted ZIP is recommended as export contains many sensitive informations like passwords of your users (even if they are hashed), but also their email addresses, and especially private keys of the realms. Directory and Single JSON file are useful especially for testing as data in the files are not protected. On the other hand, it's useful if you want to look at all your data in JSON files directly.

If you import to ZIP or Directory, you can specify also the number of users to be stored in each JSON file. So if you have very large amount of users in your database, you likely don't want to import them into single file as the file might be very big. Processing of each file is done in separate transaction as exporting/importing all users at once could also lead to memory issues.

So to export the content of your Keycloak database into encrypted ZIP, you can execute Keycloak server with the System properties like:

bin/standalone.sh -Dkeycloak.migration.action=export
-Dkeycloak.migration.provider=zip -Dkeycloak.migration.zipFile=<FILE TO EXPORT TO>
-Dkeycloak.migration.zipPassword=<PASSWORD TO DECRYPT EXPORT>

Then you can move or copy the encrypted ZIP file into second environment and you can trigger import from it into Keycloak server with the same command but use -Dkeycloak.migration.action=import instead of export .

To export into unencrypted directory you can use:

bin/standalone.sh -Dkeycloak.migration.action=export
-Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=<DIR TO EXPORT TO>

And similarly for import just use -Dkeycloak.migration.action=import instead of export .

To export into single JSON file you can use:

bin/standalone.sh -Dkeycloak.migration.action=export
-Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=<FILE TO EXPORT TO>

Here's an example of importing:

bin/standalone.sh -Dkeycloak.migration.action=import
-Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=<FILE TO IMPORT>
-Dkeycloak.migration.strategy=OVERWRITE_EXISTING

Other available options are:

-Dkeycloak.migration.realmName

can be used if you want to export just one specified realm instead of all. If not specified, then all realms will be exported.

-Dkeycloak.migration.usersExportStrategy

can be used to specify for ZIP or Directory providers to specify where to import users. Possible values are:

  • DIFFERENT_FILES - Users will be exported into more different files according to maximum number of users per file. This is default value
  • SKIP - exporting of users will be skipped completely
  • REALM_FILE - All users will be exported to same file with realm (So file like "foo-realm.json" with both realm data and users)
  • SAME_FILE - All users will be exported to same file but different than realm (So file like "foo-realm.json" with realm data and "foo-users.json" with users)

-Dkeycloak.migration.usersPerFile

can be used to specify number of users per file (and also per DB transaction). It's 5000 by default. It's used only if usersExportStrategy is DIFFERENT_FILES

-Dkeycloak.migration.strategy

is used during import. It can be used to specify how to proceed if realm with same name already exists in the database where you are going to import data. Possible values are:

  • IGNORE_EXISTING - Ignore importing if realm of this name already exists
  • OVERWRITE_EXISTING - Remove existing realm and import it again with new data from JSON file. If you want to fully migrate one environment to another and ensure that the new environment will contain same data like the old one, you can specify this.

When importing realm files that weren't exported before, the option keycloak.import can be used. If more than one realm file needs to be imported, a comma separated list of file names can be specified. This is more appropriate than the cases before, as this will happen only after the master realm has been initialized. Examples:

  • -Dkeycloak.import=/tmp/realm1.json
  • -Dkeycloak.import=/tmp/realm1.json,/tmp/realm2.json

By default, Keycloak caches realm metadata and users. There are two separate caches, one for realm metadata (realm, application, client, roles, etc...) and one for users. These caches greatly improves the performance of the server.

Keycloak supports SAML 2.0 for registered applications. Both POST and Redirect bindings are supported. You can choose to require client signature validation and can have the server sign and/or encrypt responses as well. We do not yet support logout via redirects. All logouts happen via a background POST binding request to the application that will be logged out. We do not support SAML 1.1 either. If you want support for either of those, please log a JIRA request and we'll schedule it.

When you create an application in the admin console, you can choose which protocol the application will log in with. In the application create screen, choose saml from the protocol list. After that there are a bunch of configuration options. Here is a description of each item:

Include AuthnStatement

SAML login responses may specify the authentication method used (password, etc.) as well as a timestamp of the login. Setting this to on will include that statement in the response document.

Multi-valued Roles

If this switch is off, any user role mappings will have a corresponding attribute created for it. If this switch is turn on, only one role attribute will be created, but it will have multiple values within in.

Sign Documents

When turned on, Keycloak will sign the document using the realm's private key.

Sign Assertions

With the Sign Documents switch signs the whole document. With this setting you just assign the assertions of the document.

Signature Algorithm

Choose between a variety of algorithms for signing SAML documents.

Encrypt Assertions

Encrypt assertions in SAML documents with the realm's private key. The AES algorithm is used with a key size of 128 bits.

Client Signature Required

Expect that documents coming from a client are signed. Keycloak will validate this signature using the client keys set up in the Application Keys submenu item.

Force POST Binding

By default, Keycloak will respond using the initial SAML binding of the original request. By turning on this switch, you will force Keycloak to always respond using the SAML POST Binding even if the original request was the Redirect binding.

Front Channel Logout

If true, this application requires a browser redirect to be able to perform a logout. For example, the application may require a cookie to be reset which could only be done by a done via a redirect. If this switch is false, then Keycloak will invoke a background SAML request to logout the application.

Force Name ID Format

If the request has a name ID policy, ignore it and used the value configured in the admin console under Name ID Format

Name ID Format

Name ID Format for the subject. If no name ID policy is specified in the request or if the Force Name ID Format attribute is true, this value is used.

Master SAML Processing URL

This URL will be used for all SAML requests and responsed directed to the SP. It will be used as the Assertion Consumer Service URL and the Single Logout Service URL. If a login request contains the Assertion Consumer Service URL, that will take precedence, but this URL must be valided by a registered Valid Redirect URI pattern

Assertion Consumer Service POST Binding URL

POST Binding URL for the Assertion Consumer Service.

Assertion Consumer Service Redirect Binding URL

Redirect Binding URL for the Assertion Consumer Service.

Logout Service POST Binding URL

POST Binding URL for the Logout Service.

Logout Service Redirect Binding URL

Redirect Binding URL for the Logout Service.

For login to work, Keycloak needs to be able to resolve the URL for the Assertion Consumer Service of the SP. If you are relying on the SP to provide this URL in the login request, then you must register valid redirect uri patterns so that this URL can be validated. You can set the Master SAML Processing URL as well, or alternatively, you can specify the Assertion Consumer Service URL per binding.

For logout to work, you must specify a Master SAML Processing URL, or the Loging Service URL for the binding you want Keycloak to use.

One thing to note is that roles are not treated as a hierarchy. So, any role mappings will just be added to the role attributes in the SAML document using their basic name. So, if you have multiple application roles you might have name collisions. You can use the Scope Mapping menu item to control which role mappings are set in the response.

If you go into the admin console in the application list menu page you will see an Import button. If you click on that you can import SAML Service Provider definitions using the Entity Descriptor format described in SAML 2.0. You should review all the information there to make sure everything is set up correctly.

Each realm has a URL where you can view the XML entity descriptor for the IDP. root/auth/realms/{realm}/protocol/saml/descriptor

This chapter discusses possible security vulnerabilities Keycloak could have, how Keycloak mitigates those vulnerabilities, and what steps you need to do to configure Keycloak to mitigate some vulnerabilities. A good list of potential vulnerabilities and what security implementations should do to mitigate them can be found in the OAuth 2.0 Threat Model document put out by the IETF. Many of those vulnerabilities are discussed here.

If you do not use SSL/HTTPS for all communication between the Keycloak auth server and the clients it secures you will be very vulnerable to man in the middle attacks. OAuth 2.0/OpenID Connect uses access tokens for security. Without SSL/HTTPS, attackers can sniff your network and obtain an access token. Once they have an access token they can do any operation that the token has been given permission for.

Keycloak has three modes for SSL/HTTPS. SSL can be hard to set up, so out of the box, Keycloak allows non-HTTPS communication over private IP addresses like localhost, 192.168.x.x, and other private IP addresses. In production, you should make sure SSL is enabled and required across the board.

On the adapter/client side, Keycloak allows you to turn off the SSL trust manager. The trust manager ensures identity the client is talking to. It checks the DNS domain name against the server's certificate. In production you should make sure that each of your client adapters is configured to use a truststore. Otherwise you are vulnerable to DNS man in the middle attacks.

A brute force attack happens when an attacker is trying to guess a user's password. Keycloak has some limited brute force detection capabilities. If turned on, a user account will be temporarily disabled if a threshold of login failures is reached. The downside of this is that this makes Keycloak vulnerable to denial of service attacks. Eventually we will expand this functionality to take client IP address into account when deciding whether to block a user.

Another thing you can do to prevent password guessing is to point a tool like Fail2Ban to the Keycloak server's log file. Keycloak logs every login failure and client IP address that had the failure.

In the admin console, per realm, you can set up a password policy to enforce that users pick hard to guess passwords. A password has to match all policies. The password policies that can be configured are hash iterations, length, digits, lowercase, uppercase, special characters, not username, regex patterns, password history and force expired password update. Force expired password update policy forces or requires password updates after specified span of time. Password history policy restricts a user from resetting his password to N old expired passwords. Multiple regex patterns, separated by comma, can be specified in regex pattern policy. If there's more than one regex added, password has to match all fully. Increasing number of Hash Iterations (n) does not worsen anything (and certainly not the cipher) and it greatly increases the resistance to dictionary attacks. However the drawback to increasing n is that it has some cost (CPU usage, energy, delay) for the legitimate parties. Increasing n also slightly increases the odds that a random password gives the same result as the right password due to hash collisions, and is thus a false but accepted password; however that remains very unlikely, in the order of n*[1/(2^256)] for practical values of n, and can be entirely ignored in practice. Keycloak also uses PBKDF2 internally to cryptographically derive passwords to refine and improve the ratio of cost between attacker and legitimate parties. Good practice is to pay attention to the time complexity of hash_password and hash; then increase n as much as tolerable in the situation(s) at hand and and revise parameters such as n every few years to account for time complexity trade off.

Finally, the best way to mitigate against brute force attacks is to require user to set up a one-time-password (OTP).

To improve availability and scalability Keycloak can be deployed in a cluster.

It's fairly straightforward to configure a Keycloak cluster, the steps required are:

  • Configure a shared database

  • Configure Infinispan

  • Enable realm and user cache invalidation

  • Enable distributed user sessions

  • Start in HA mode

Keycloak uses Infinispan caches to share information between nodes.

For realm and users Keycloak uses a invalidation cache. An invalidation cache doesn't share any data, but simply removes stale data from remote caches. This reduces network traffic, as well as preventing sensitive data (such as realm keys and password hashes) from being sent between the nodes.

User sessions and login failures supports either distributed caches or fully replicated caches. We recommend using a distributed cache.

To configure the required Infinspan caches open standalone/configuration/standalone-ha.xml and add:


<subsystem xmlns="urn:jboss:domain:infinispan:2.0">
    <cache-container name="keycloak" jndi-name="infinispan/Keycloak" start="EAGER">
        <transport lock-timeout="60000"/>
        <invalidation-cache name="realms" mode="SYNC" start="EAGER"/>
        <invalidation-cache name="users" mode="SYNC" start="EAGER"/>
        <distributed-cache name="sessions" mode="SYNC" owners="1" start="EAGER"/>
        <distributed-cache name="loginFailures" mode="SYNC" owners="1" start="EAGER"/>
    </cache-container>
    ...
</subsystem>

For more advanced options refer to the Infinispan Subsystem and Infinispan documentation.

Next open standalone/configuration/keycloak-server.json and add:

"connectionsInfinispan": {
    "default" : {
        "cacheContainer" : "java:jboss/infinispan/Keycloak"
    }
}

By default there's nothing to prevent unauthorized nodes from joining the cluster and sending potentially malicious messages to the cluster. However, as there's no sensitive data sent there's not much that can be achieved. For realms and users all that can be done is to send invalidation messages to make nodes load data from the database more frequently. For user sessions it would be possible to modify existing user sessions, but creating new sessions would have no affect as they would not be linked to any access tokens. There's not too much that can be achieved by modifying user sessions. For example it would be possible to prevent sessions from expiring, by changing the creation time. However, it would for example have no effect adding additional permissions to the sessions as these are rechecked against the user and application when the token is created or refreshed.

In either case your cluster nodes should be in a private network, with a firewall protecting them from outside attacks. Ideally isolated from workstations and laptops. You can also enable encryption of cluster messages, this could for example be useful if you can't isolate cluster nodes from workstations and laptops on your private network. However, encryption will obviously come at a cost of reduced performance.

To enable encryption of cluster messages you first have to create a shared keystore (change the key and store passwords!):


# keytool -genseckey -alias keycloak -keypass <PASSWORD> -storepass <PASSWORD> \
 -keyalg Blowfish -keysize 56 -keystore defaultStore.keystore -storetype JCEKS

Copy this keystore to all nodes (for example to standalone/configuration). Then configure JGroups to encrypt all messages by adding the ENCRYPT protocol to the JGroups sub-system (this should be added after the pbcast.GMS protocol):


<subsystem xmlns="urn:jboss:domain:jgroups:2.0" default-stack="udp">
    <stack name="udp">
        ...
        <protocol type="pbcast.GMS"/>
        <protocol type="ENCRYPT">
            <property name="key_store_name">
                ${jboss.server.config.dir}/defaultStore.keystore
            </property>
            <property name="key_password">PASSWORD</property>
            <property name="store_password">PASSWORD</property>
            <property name="alias">keycloak</property>
        </protocol>
        ...
    </stack>
    <stack name="tcp">
        ...
        <protocol type="pbcast.GMS"/>
        <protocol type="ENCRYPT">
            <property name="key_store_name">
                ${jboss.server.config.dir}/defaultStore.keystore
            </property>
            <property name="key_password">PASSWORD</property>
            <property name="store_password">PASSWORD</property>
            <property name="alias">keycloak</property>
        </protocol>
        ...
    </stack>
    ...
</subsystem>

See the JGroups manual for more details.

This chapter is focused on clustering support for your own AS7, EAP6 or Wildfly applications, which are secured by Keycloak. We support various deployment scenarios according if your application is:

  • stateless or stateful

  • distributable (replicated http session) or non-distributable and just relying on sticky sessions provided by loadbalancer

  • deployed on same or different cluster hosts where keycloak servers are deployed

The situation is a bit tricky as application communicates with Keycloak directly within user's browser (for example redirecting to login screen), but there is also backend (out-of-bound) communication between keycloak and application, which is hidden from end-user and his browser and hence can't rely on sticky sessions.

By default, the servlet web application secured by Keycloak uses HTTP session to store information about authenticated user account. This means that this info could be replicated across cluster and your application will safely survive failover of some cluster node.

However if you don't need or don't want to use HTTP Session, you may alternatively save all info about authenticated account into cookie. This is useful especially if your application is:

  • stateless application without need of HTTP Session, but with requirement to be safe to failover of some cluster node

  • stateful application, but you don't want sensitive token data to be saved in HTTP session

  • stateless application relying on loadbalancer, which is not aware of sticky sessions (in this case cookie is your only way)

To configure this, you can add this line to configuration of your adapter in WEB-INF/keycloak.json of your application:


"token-store": "cookie"

Default value of token-store is session, hence saving data in HTTP session.

One limitation of cookie store is, that whole info about account is passed in cookie KEYCLOAK_ADAPTER_STATE in each HTTP request. Hence it's not the best for network performance. Another small limitation is limited support for Single-Sign out. It works without issues if you init servlet logout (HttpServletRequest.logout) from this application itself as the adapter will delete the KEYCLOAK_ADAPTER_STATE cookie. But back-channel logout initialized from different application can't be propagated by Keycloak to this application with cookie store. Hence it's recommended to use very short value of access token timeout (1 minute for example).

Admin URL for particular application can be configured in Keycloak admin console. It's used by Keycloak server to send backend requests to application for various tasks, like logout users or push revocation policies.

For example logout of user from Keycloak works like this:

  1. User sends logout request from one of applications where he is logged.

  2. Then application will send logout request to Keycloak

  3. Keycloak server logout user in itself, and then it re-sends logout request by backend channel to all applications where user is logged. Keycloak is using admin URL for this. So logout is propagated to all apps.

You may again use relative values for admin URL, but in cluster it may not be the best similarly like in previous section .

Some examples of possible values of admin URL are:

http://${jboss.host.name}:8080/myapp

This is best choice if "myapp" is deployed on same cluster hosts like Keycloak and is distributable. In this case Keycloak server sends logout request to itself, hence no communication with loadbalancer or other cluster nodes and no additional network traffic.

Note that since the application is distributable, the backend request sent by Keycloak could be served on any application cluster node as invalidation of HTTP Session on node1 will propagate the invalidation to other cluster nodes due to replicated HTTP sessions.

http://${application.session.host}:8080/myapp

Keycloak will track hosts where is particular HTTP Session served and it will send session invalidation message to proper cluster node.

For example application is deployed on http://node1:8080/myapp and http://node2:8080/myapp . Now HTTP Session session1 is sticky-session served on cluster node node2 . When keycloak invalidates this session, it will send request directly to http://node2:8080/myapp .

This is ideal configuration for distributable applications deployed on different host than keycloak or for non-distributable applications deployed either on same or different nodes than keycloak. Good thing is that it doesn't send requests through load-balancer and hence helps to reduce network traffic.

Previous section describes how can Keycloak send logout request to proper application node. However in some cases admin may want to propagate admin tasks to all registered cluster nodes, not just one of them. For example push new notBefore for realm or application, or logout all users from all applications on all cluster nodes.

In this case Keycloak should be aware of all application cluster nodes, so it could send event to all of them. To achieve this, we support auto-discovery mechanism:

  1. Once new application node joins cluster, it sends registration request to Keycloak server

  2. The request may be re-sent to Keycloak in configured periodic intervals

  3. If Keycloak won't receive re-registration request within specified timeout (should be greater than period from point 2) then it automatically unregister particular node

  4. Node is also unregistered in Keycloak when it sends unregistration request, which is usually during node shutdown or application undeployment. This may not work properly for forced shutdown when undeployment listeners are not invoked, so here you need to rely on automatic unregistration from point 3 .

Sending startup registrations and periodic re-registration is disabled by default, as it's main usecase is just cluster deployment. In WEB-INF/keycloak.json of your application, you can specify:


"register-node-at-startup": true,
"register-node-period": 600,

which means that registration is sent at startup (accurately when 1st request is served by the application node) and then it's resent each 10 minutes.

In Keycloak admin console you can specify the maximum node re-registration timeout (makes sense to have it bigger than register-node-period from adapter configuration for particular application). Also you can manually add and remove cluster nodes in admin console, which is useful if you don't want to rely on adapter's automatic registration or if you want to remove stale application nodes, which weren't unregistered (for example due to forced shutdown).

By default, application adapter tries to refresh access token when it's expired (period can be specified as Access Token Lifespan) . However if you don't want to rely on the fact, that Keycloak is able to successfully propagate admin events like logout to your application nodes, then you have possibility to configure adapter to refresh access token in each HTTP request.

In WEB-INF/keycloak.json you can configure:


"always-refresh-token": true

Note that this has big performance impact. It's useful just if performance is not priority, but security is critical and you can't rely on logout and push notBefore propagation from Keycloak to applications.

Keycloak has an HTTP(S) proxy that you can put in front of web applications and services where it is not possible to install the keycloak adapter. You can set up URL filters so that certain URLs are secured either by browser login and/or bearer token authentication. You can also define role constraints for URL patterns within your applications.

Here's an example configuration file.

{
    "target-url": "http://localhost:8082",
    "send-access-token": true,
    "bind-address": "localhost",
    "http-port": "8080",
    "https-port": "8443",
    "keystore": "classpath:ssl.jks",
    "keystore-password": "password",
    "key-password": "password",
    "applications": [
        {
            "base-path": "/customer-portal",
            "error-page": "/error.html",
            "adapter-config": {
                "realm": "demo",
                "resource": "customer-portal",
                "realm-public-key": "MIGfMA0GCSqGSIb",
                "auth-server-url": "http://localhost:8081/auth",
                "ssl-required" : "external",
                "principal-attribute": "name",
                "credentials": {
                    "secret": "password"
                }
            }
            ,
            "constraints": [
                {
                    "pattern": "/users/*",
                    "roles-allowed": [
                        "user"
                    ]
                },
                {
                    "pattern": "/admins/*",
                    "roles-allowed": [
                        "admin"
                    ]
                },
                {
                    "pattern": "/users/permit",
                    "permit": true
                },
                {
                    "pattern": "/users/deny",
                    "deny": true
                }
            ]
        }
    ]
}

The basic configuration options for the server are as follows:

target-url

The URL this server is proxying REQUIRED..

send-access-token

Boolean flag. If true, this will send the access token via the KEYCLOAK_ACCESS_TOKEN header to the proxied server. OPTIONAL.. Default is false.

bind-address

DNS name or IP address to bind the proxy server's sockets to. OPTIONAL.. The default value is localhost

http-port

Port to listen for HTTP requests. If you do not specify this value, then the proxy will not listen for regular HTTP requests. OPTIONAL..

https-port

Port to listen for HTTPS requests. If you do not specify this value, then the proxy will not listen for HTTPS requests. OPTIONAL..

keystore

Path to a Java keystore file that contains private key and certificate for the server to be able to handle HTTPS requests. Can be a file path, or, if you prefix it with classpath: it will look for this file in the classpath. OPTIONAL.. If you have enabled HTTPS, but have not defined a keystore, the proxy will auto-generate a self-signed certificate and use that.

buffer-size

HTTP server socket buffer size. Usually the default is good enough. OPTIONAL..

buffers-per-region

HTTP server socket buffers per region. Usually the default is good enough. OPTIONAL..

io-threads

Number of threads to handle IO. Usually default is good enough. OPTIONAL.. The default is the number of available processors * 2.

worker-threads

Number of threads to handle requests. Usually the default is good enough. OPTIONAL.. The default is the number of available processors * 16.

Next under the applications array attribute, you can define one or more applications per host you are proxying.

If you have custom user data you want to store and manage in the admin console, registration page, and user account service, you can easily add support for it by extending and modifying various Keycloak themes.

To be able to enter custom attributes in the admin console, take the following steps

  1. Create a new theme within the themes/admin/mytheme directory in your distribution. Where mytheme is whatever you want to name your theme.
  2. Create a theme.properties file in this directory that extends the main admin console theme.
    parent=keycloak
    import=common/keycloak
    
  3. Copy the file themes/admin/base/resources/partials/user-attribute-entry.html into the a mirror directory in your theme: themes/admin/mytheme/resources/partials/user-attribute-entry.html. What you are doing here is overriding the user attribute entry page in the admin console and putting in what attributes you want. This file already contains an example of entering address data. You can remove this if you want and replace it with something else. Also, if you want to edit this file directly instead of creating a new theme, you can.
  4. In the user-attribute-entry.html file add your custom user attribute entry form item. For example
        <div class="form-group clearfix block">
            <label class="col-sm-2 control-label" for="mobile">Mobile</label>
            <div class="col-sm-6">
                <input ng-model="user.attributes.mobile" class="form-control" type="text" name="mobile" id="mobile" />
            </div>
            <span tooltip-placement="right" tooltip="Mobile number." class="fa fa-info-circle"></span>
        </div>
    
    The ng-model names the user attribute you will store in the database and must have the form of user.attributes.ATTR_NAME.
  5. Change the theme for the admin console. Save it, then refresh your browser, and you should now see these fields in the User detail page for any user.

To be able to enter custom attributes in the registration page, take the following steps

  1. Create a new theme within the themes/login/mytheme directory in your distribution. Where mytheme is whatever you want to name your theme.
  2. Create a theme.properties file in this directory that extends the main admin console theme.
    parent=keycloak
    import=common/keycloak
    styles= ../patternfly/lib/patternfly/css/patternfly.css ../patternfly/css/login.css ../patternfly/lib/zocial/zocial.css css/login.css
  3. Copy the file themes/login/base/register.ftl into the a mirror directory in your theme: themes/login/mytheme/register.ftl. What you are doing here is overriding the registration page and adding what attributes you want. This file already contains an example of entering address data. You can remove this if you want and replace it with something else. Also, if you want to edit this file directly instead of creating a new theme, you can.
  4. In the register.ftl file add your custom user attribute entry form item. For example
    <div class="form-group">
       <div class="${properties.kcLabelWrapperClass!}">
           <label for="user.attributes.mobile" class="${properties.kcLabelClass!}">Mobile number</label>
       </div>
    
       <div class="col-sm-10 col-md-10">
           <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.mobile" name="user.attributes.mobile"/>
       </div>
    </div>
    
    Make sure the input field id ane name match the user attribute you want to store in the database. This must have the form of user.attributes.ATTR_NAME. You might also want to replace the label text with a message property. This will help later if you want to internationalize your pages.
  5. Change the theme for the login to your new theme. Save it, then refresh your browser, and you should now see these fields in the registration.

To be able to manage custom attributes in the user account profile page, take the following steps

  1. Create a new theme within the themes/account/mytheme directory in your distribution. Where mytheme is whatever you want to name your theme.
  2. Create a theme.properties file in this directory that extends the main admin console theme.
    parent=patternfly
    import=common/keycloak
    
    styles= ../patternfly/lib/patternfly/css/patternfly.css ../patternfly/css/account.css css/account.css
  3. Copy the file themes/account/base/account.ftl into the a mirror directory in your theme: themes/account/mytheme/account.ftl. What you are doing here is overriding the profile page and adding what attributes you want to manage. This file already contains an example of entering address data. You can remove this if you want and replace it with something else. Also, if you want to edit this file directly instead of creating a new theme, you can.
  4. In the account.ftl file add your custom user attribute entry form item. For example
    <div class="form-group">
       <div class="col-sm-2 col-md-2">
           <label for="user.attributes.mobile" class="control-label">Mobile number</label>
       </div>
    
       <div class="col-sm-10 col-md-10">
           <input type="text" class="form-control" id="user.attributes.mobile" name="user.attributes.mobile" value="${(account.attributes.mobile!'')?html}"/>
       </div>
    </div>
    Make sure the input field id ane name match the user attribute you want to store in the database. This must have the form of user.attributes.ATTR_NAME. You might also want to replace the label text with a message property. This will help later if you want to internationalize your pages.
  5. Change the theme for the account to your new theme. Save it, then refresh your browser, and you should now see these fields in the account profile page.

Applications that receive ID Tokens, Access Tokens, or SAML assertions may need or want different user metadata and roles. Keycloak allows you to define what exactly is transferred. You can hardcode roles, claims and custom attributes. You can pull user metadata into a token or assertion. You can rename roles. Basicall you have a lot of control of what exactly goes back to the client.

Within the admin console, if you go to an application you've registered, you'll see a "Mappers" sub-menu item. This is the place where you can control how a OIDC ID Token, Access Token, and SAML login response assertions look like. When you click on this you'll see some default mappers that have been set up for you. Clicking the "Add Builtin" button gives you the option to add other preconfigured mappers. Clicking on "Create" allows you to define your own protocol mappers. The tooltips are very helpful to learn exactly what you can do to tailor your tokens and assertions. They should be enough to guide you through the process.

To upgrade to a new version of Keycloak first download and install the new version of Keycloak. You then have to migrate the database, keycloak-server.json, providers, themes and applications from the old version.

Previously there was Claims tab in admin console for application and OAuth clients. This was used to configure which attributes should go into access token for particular application/client. This was removed and replaced with Protocol mappers, which are more flexible.

You don't need to care about migration of database from previous version. We did migration scripts for both RDBMS and Mongo, which should ensure that claims configured for particular application/client will be converted into corresponding protocol mappers (Still it's safer to backup DB before migrating to newer version though). Same applies for exported JSON representation from previous version.

We refactored social providers SPI and replaced it with identity brokering SPI, which is more flexible. The Social tab in admin console is renamed to Identity Provider tab.

Again you don't need to care about migration of database from previous version similarly like for Claims/protocol mappers. Both configuration of social providers and "social links" to your users will be converted to corresponding Identity providers.

Only required action from you would be to change allowed Redirect URI in the admin console of particular 3rd party social providers. You can first go to the Keycloak admin console and copy Redirect URI from the page where you configure the identity provider. Then you can simply paste this as allowed Redirect URI to the admin console of 3rd party provider (IE. Facebook admin console).