Keycloak Quickstarts

repository·main·Indexed 25 days ago

https://github.com/keycloak/keycloak-quickstarts

A collection of reference implementations and examples for securing applications (Node.js, Spring, Jakarta, etc.) with Keycloak and extending Keycloak's functionality using Java SPIs. Includes guides on implementing OAuth 2.0 Device Authorization Grant with Spring Boot, using Action Tokens with authenticators and required actions to invoke external applications, and building custom authenticator providers.

Tokens
28.4K
Snippets
84
Records
138
Agent score
81%

What's inside keycloak-quickstarts

  1. Overview of Keycloak Quickstarts categories

    main

    The Keycloak Quickstarts repository provides small, specific, working examples for securing applications and extending Keycloak server capabilities. The examples are organized into the following categories:

    CategoryDescription
    extensionExamples of extending server capabilities using Keycloak SPIs
    jakartaExamples for securing Jakarta Applications
    jsExamples for securing JavaScript Applications
    nodejsExamples for securing NodeJS Applications
    proxyExamples for deploying Keycloak behind a reverse proxy
    springExamples for securing Spring Applications

    For Quarkus-specific security implementations, refer to the official Quarkus guides for Client Application and Resource Server Application security.

  2. Overview of jakarta-servlet-authz-client

    main

    The jakarta-servlet-authz-client is a beginner-level Jakarta EE quickstart that demonstrates how to protect a Servlet application using Elytron OIDC and Keycloak Authorization Services.

    It showcases fine-grained authorization by:

    1. Protecting specific resources (Regular, Premium, and Admin areas).
    2. Building a dynamic menu based on permissions obtained from the Keycloak Server.
    3. Using the AuthorizationContext object to determine allowed resources and scopes, and to perform additional application-level permission checks.
  3. Deploy Keycloak behind a reverse proxy

    main

    The Proxy Quickstarts provide examples for deploying clustered Keycloak instances behind different reverse proxies using two primary TLS modes:

    Supported Proxies

    • HAProxy
    • Traefik

    TLS Modes

    • TLS Passthrough: The proxy passes the encrypted traffic directly to Keycloak without decrypting it. This is useful if you want Keycloak to handle TLS termination directly.
    • TLS Re-encrypt: The proxy terminates the incoming TLS connection and then initiates a new TLS connection to the Keycloak backend. This provides an extra layer of security by ensuring traffic is encrypted both from the client to the proxy and from the proxy to Keycloak.
    | Proxy   | Mode                                    | Description                                                           |
    |---------|-----------------------------------------|-----------------------------------------------------------------------|
    | HAProxy | [TLS Passthrough](haproxy/passthrough)  | Two clustered Keycloak instances behind HAProxy with TLS passthrough. |
    | HAProxy | [TLS Re-encrypt](haproxy/reencrypt)     | Two clustered Keycloak instances behind HAProxy with TLS re-encrypt.  |
    | Traefik | [TLS Passthrough](traefik/passthrough)  | Two clustered Keycloak instances behind Traefik with TLS passthrough.  |
    | Traefik | [TLS Re-encrypt](traefik/reencrypt)     | Two clustered Keycloak instances behind Traefik with TLS re-encrypt.  |
  4. What is the User Storage JPA Quickstart?

    main

    This quickstart demonstrates how to implement the Keycloak User Storage SPI using JPA. It provides a template for integrating Keycloak with an existing external custom user database.

    In this specific example, a relational database schema containing a single user table (storing username, email, phone number, and password) is mapped to the Keycloak user metamodel, allowing the Keycloak runtime to consume these external users as if they were native Keycloak users.

  5. What is TLS passthrough in Traefik?

    main

    In TLS passthrough mode, Traefik operates at the TCP layer (Layer 4) and forwards encrypted TLS traffic directly to backend servers without decrypting it. This means:

    • Keycloak holds the TLS certificate and private key, not the proxy.
    • Traefik cannot inspect, modify, or cache HTTP headers or the request body.
    • End-to-end encryption is preserved between the client and Keycloak.
    • Traefik uses the PROXY protocol v2 to pass the original client IP address to Keycloak.
  6. What is TLS re-encrypt in Traefik?

    main

    In TLS re-encrypt mode, Traefik acts as a Layer 7 load balancer that decrypts incoming HTTPS connections and then establishes a new HTTPS connection to the backend services (e.g., Keycloak).

    Key characteristics:

    • Header Inspection: Traefik can inspect and modify HTTP headers and request bodies.
    • Authentication: Traefik uses its own TLS certificate/key to authenticate to the client, and its own TLS certificate/key to authenticate to the backend Keycloak instances.
    • Client Certificate Forwarding: Traefik can optionally accept a client certificate during the TLS handshake and forward it to Keycloak via the X-Forwarded-Tls-Client-Cert HTTP header.
  7. Understand the OAuth 2.0 Device Flow mechanism

    main

    The Device Flow follows a specific request/response pattern between the client application, Keycloak, and the user:

    1. Device Authorization Request: The application requests a device code from Keycloak.

      POST /realms/device-flow-quickstart/protocol/openid-connect/auth/device
      client_id=device-client
      scope=openid profile
    2. Device Authorization Response: Keycloak returns the following keys:

      • device_code: Used for polling.
      • user_code: Shown to the user for manual entry.
      • verification_uri: The URL for user authorization.
      • verification_uri_complete: The URL with the user_code pre-filled.
      • expires_in: Lifespan of the codes.
      • interval: Recommended polling interval.
    3. User Authorization: The user visits the verification_uri on a secondary device, logs in, and approves the request.

    4. Token Polling: The application polls the token endpoint using the device_code until authorized.

      POST /realms/device-flow-quickstart/protocol/openid-connect/token
      grant_type=urn:ietf:params:oauth:grant-type:device_code
      client_id=device-client
      device_code={device_code}
    5. Token Response: Keycloak returns the access token.

    # Device Authorization Request
    POST /realms/device-flow-quickstart/protocol/openid-connect/auth/device
    client_id=device-client
    scope=openid profile
    
    # Token Polling Request
    POST /realms/device-flow-quickstart/protocol/openid-connect/token
    grant_type=urn:ietf:params:oauth:grant-type:device_code
    client_id=device-client
    device_code={device_code}
  8. Extend the Keycloak Admin UI with SPI

    main

    You can extend the Keycloak Admin UI by implementing Service Provider Interfaces (SPI) to either add a new tab to an existing page or create an entirely new section in the side menu.

    Implementation Options

    • New Menu Section: Implement org.keycloak.services.ui.extend.UiPageProvider to add a complete section to the main menu.
    • New Tab: Implement org.keycloak.services.ui.extend.UiTabProvider to add a tab to an existing page.

    Configuration Requirements

    • Field Definitions: For both options, you must describe the fields for your page using org.keycloak.provider.ProviderConfigProperty.
    • UI Placement: To specify where a tab appears, provide a valid path. Valid paths can be found in the routes.ts files within the admin-ui module of the Keycloak project.
    • Required Feature: The declarative-ui feature must be enabled on the Keycloak server to use these SPIs.
  9. How Action Tokens and Authenticators cooperate to invoke external applications

    main

    This pattern allows you to incorporate an external application into the Keycloak authentication flow. The process follows these steps:

    1. Trigger: A custom authenticator is invoked during the authentication flow.
    2. Redirect: The authenticator prepares an Action Token for the current session and redirects the user to an external application, passing the token.
    3. External Processing: The external application performs its specific logic (e.g., collecting custom user attributes).
    4. Return: The application uses the action token to redirect the user back to Keycloak, providing a signed token containing the data collected.
    5. Completion: A Keycloak handler processes the action token and updates the authenticating user's attributes based on the token's contents.
  10. Handle Device Flow polling responses

    main

    When polling the token endpoint for a device code, the application must handle specific response codes to manage the lifecycle of the authorization process:

    • authorization_pending: The user has not yet completed the authorization; the application should continue polling.
    • slow_down: The application is polling too frequently; it should log a message and adjust its interval.
    • access_denied: The user or administrator denied the request; the application must stop polling and display an error.
    • expired_token: The device code has expired; the application must stop polling and display an error.

    Polling stops successfully once an access token is received.

  11. Enable Sticky Sessions for Keycloak HA with HAProxy

    main

    To improve performance and reduce cross-node traffic in a Keycloak cluster using embedded caches, use HAProxy to route requests to the specific node that owns the session. This is achieved by inspecting the AUTH_SESSION_ID cookie.

    1. Configure Keycloak Node Names

    Each Keycloak instance must have a stable, predictable node name. Set the KC_SPI_CACHE_EMBEDDED__DEFAULT__NODE_NAME environment variable for each instance.

    2. Configure HAProxy Routing

    Use the use-server directive to check if the AUTH_SESSION_ID cookie ends with the specific node name.

    # Route based on the AUTH_SESSION_ID cookie suffix
    use-server keycloak1 if { req.cook(AUTH_SESSION_ID) -m end keycloak1 }
    use-server keycloak2 if { req.cook(AUTH_SESSION_ID) -m end keycloak2 }

    Note: Requests without the cookie (initial requests, API calls) will fall back to the default balance roundrobin strategy.

    use-server keycloak1 if { req.cook(AUTH_SESSION_ID) -m end keycloak1 }
    use-server keycloak2 if { req.cook(AUTH_SESSION_ID) -m end keycloak2 }
  12. How Action Tokens and Required Actions cooperate to invoke external applications

    main

    This pattern allows you to integrate an external application into the Keycloak authentication flow to perform specific tasks (like collecting user attributes) that Keycloak cannot do natively.

    The Workflow:

    1. Trigger: During authentication, a Keycloak Required Action is invoked.
    2. Redirect: The required action generates an Action Token for the current session and redirects the user to an external application, passing the token in the URL.
    3. External Processing: The external application performs its task (e.g., a user fills out a form) and obtains the token.
    4. Return: The application redirects the user back to Keycloak, providing a signed token containing the new data.
    5. Completion: A Keycloak Action Token Handler processes the returned token, extracts the values, and updates the user's attributes, allowing the authentication flow to continue.