CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-keycloak--keycloak-adapter-core

Core functionality for Keycloak OIDC/OAuth2 client adapters enabling Java applications to integrate with Keycloak identity and access management services

Pending
Overview
Eval results
Files

http-operations.mddocs/

HTTP Operations

HTTP client builder with SSL configuration and server request utilities for token operations, logout, and node registration. This module provides secure HTTP communication capabilities with Keycloak servers and comprehensive request handling utilities.

Capabilities

HttpClientBuilder

Builder for creating configured HttpClient instances with SSL support and connection management.

/**
 * Builder for creating configured HttpClient instances with SSL support and connection management
 */
public class HttpClientBuilder {
    /**
     * Set socket timeout for HTTP operations
     * @param timeout Timeout value
     * @param unit Time unit for timeout
     * @return Builder instance for chaining
     */
    public HttpClientBuilder socketTimeout(long timeout, TimeUnit unit);
    
    /**
     * Set connection establishment timeout
     * @param timeout Timeout value for connection establishment
     * @param unit Time unit for timeout
     * @return Builder instance for chaining
     */
    public HttpClientBuilder establishConnectionTimeout(long timeout, TimeUnit unit);
    
    /**
     * Set connection time-to-live
     * @param ttl Time-to-live value
     * @param unit Time unit for TTL
     * @return Builder instance for chaining
     */
    public HttpClientBuilder connectionTTL(long ttl, TimeUnit unit);
    
    /**
     * Set maximum connections per route
     * @param maxPooledPerRoute Maximum connections per route
     * @return Builder instance for chaining
     */
    public HttpClientBuilder maxPooledPerRoute(int maxPooledPerRoute);
    
    /**
     * Set total connection pool size
     * @param connectionPoolSize Total pool size
     * @return Builder instance for chaining
     */
    public HttpClientBuilder connectionPoolSize(int connectionPoolSize);
    
    /**
     * Disable trust manager (accept all certificates)
     * WARNING: Only use for development/testing
     * @return Builder instance for chaining
     */
    public HttpClientBuilder disableTrustManager();
    
    /**
     * Configure cookie cache behavior
     * @param disable Whether to disable cookie caching
     * @return Builder instance for chaining
     */
    public HttpClientBuilder disableCookieCache(boolean disable);
    
    /**
     * Set hostname verification policy
     * @param policy Hostname verification policy
     * @return Builder instance for chaining
     */
    public HttpClientBuilder hostnameVerification(HostnameVerificationPolicy policy);
    
    /**
     * Set custom SSL context
     * @param sslContext Configured SSL context
     * @return Builder instance for chaining
     */
    public HttpClientBuilder sslContext(SSLContext sslContext);
    
    /**
     * Set trust store for server certificate validation
     * @param truststore Trust store containing trusted certificates
     * @return Builder instance for chaining
     */
    public HttpClientBuilder trustStore(KeyStore truststore);
    
    /**
     * Set client key store for mutual TLS
     * @param keyStore Key store containing client certificate and private key
     * @param password Key store password
     * @return Builder instance for chaining
     */
    public HttpClientBuilder keyStore(KeyStore keyStore, String password);
    
    /**
     * Set client key store for mutual TLS with char array password
     * @param keyStore Key store containing client certificate and private key
     * @param password Key store password as char array
     * @return Builder instance for chaining
     */
    public HttpClientBuilder keyStore(KeyStore keyStore, char[] password);
    
    /**
     * Build HTTP client with default configuration
     * @return Configured HttpClient instance
     */
    public HttpClient build();
    
    /**
     * Build HTTP client with adapter-specific configuration
     * @param adapterConfig Adapter HTTP client configuration
     * @return Configured HttpClient instance
     */
    public HttpClient build(AdapterHttpClientConfig adapterConfig);
    
    /**
     * Hostname verification policy enumeration
     */
    public enum HostnameVerificationPolicy {
        /** Accept any hostname (insecure) */
        ANY,
        /** Standard wildcard verification */
        WILDCARD,
        /** Strict hostname verification */
        STRICT
    }
}

Usage Examples:

// Basic HTTP client for Keycloak communication
HttpClient client = new HttpClientBuilder()
    .socketTimeout(30, TimeUnit.SECONDS)
    .establishConnectionTimeout(10, TimeUnit.SECONDS)
    .connectionPoolSize(20)
    .maxPooledPerRoute(5)
    .build();

// HTTP client with custom SSL configuration
KeyStore trustStore = loadTrustStore();
HttpClient secureClient = new HttpClientBuilder()
    .trustStore(trustStore)
    .hostnameVerification(HostnameVerificationPolicy.STRICT)
    .socketTimeout(60, TimeUnit.SECONDS)
    .build();

// HTTP client with mutual TLS
KeyStore clientKeyStore = loadClientKeyStore();
HttpClient mutualTlsClient = new HttpClientBuilder()
    .keyStore(clientKeyStore, "keystore-password")
    .trustStore(trustStore)
    .sslContext(createCustomSslContext())
    .build();

// Development/testing client (insecure)
HttpClient devClient = new HttpClientBuilder()
    .disableTrustManager()
    .hostnameVerification(HostnameVerificationPolicy.ANY)
    .build();

// Configure in deployment
KeycloakDeployment deployment = new KeycloakDeployment();
deployment.setClient(secureClient);

ServerRequest

Utility class for server-side operations including token management, logout, and node registration.

/**
 * Utility class for server-side operations including token management, logout, and node registration
 */
public class ServerRequest {
    /**
     * Exception thrown for HTTP operation failures
     */
    public static class HttpFailure extends Exception {
        public HttpFailure(String message);
        public HttpFailure(String message, Throwable cause);
    }
    
    /**
     * Invoke logout on Keycloak server
     * @param deployment Keycloak deployment configuration
     * @param refreshToken Refresh token to invalidate
     * @throws IOException If network operation fails
     * @throws HttpFailure If server returns error response
     */
    public static void invokeLogout(KeycloakDeployment deployment, String refreshToken) 
        throws IOException, HttpFailure;
    
    /**
     * Exchange authorization code for tokens
     * @param deployment Keycloak deployment configuration
     * @param code Authorization code from OAuth flow
     * @param redirectUri Redirect URI used in authorization request
     * @param sessionId Session identifier
     * @return Access token response containing tokens
     * @throws IOException If network operation fails
     * @throws HttpFailure If server returns error response
     */
    public static AccessTokenResponse invokeAccessCodeToToken(
        KeycloakDeployment deployment,
        String code,
        String redirectUri,
        String sessionId
    ) throws IOException, HttpFailure;
    
    /**
     * Exchange authorization code for tokens with PKCE
     * @param deployment Keycloak deployment configuration
     * @param code Authorization code from OAuth flow
     * @param redirectUri Redirect URI used in authorization request
     * @param sessionId Session identifier
     * @param codeVerifier PKCE code verifier
     * @return Access token response containing tokens
     * @throws IOException If network operation fails
     * @throws HttpFailure If server returns error response
     */
    public static AccessTokenResponse invokeAccessCodeToToken(
        KeycloakDeployment deployment,
        String code,
        String redirectUri,
        String sessionId,
        String codeVerifier
    ) throws IOException, HttpFailure;
    
    /**
     * Refresh access token using refresh token
     * @param deployment Keycloak deployment configuration
     * @param refreshToken Current refresh token
     * @return Access token response with new tokens
     * @throws IOException If network operation fails
     * @throws HttpFailure If server returns error response
     */
    public static AccessTokenResponse invokeRefresh(
        KeycloakDeployment deployment,
        String refreshToken
    ) throws IOException, HttpFailure;
    
    /**
     * Register application node with Keycloak server
     * @param deployment Keycloak deployment configuration
     * @param host Host identifier for the node
     * @throws HttpFailure If registration fails
     * @throws IOException If network operation fails
     */
    public static void invokeRegisterNode(KeycloakDeployment deployment, String host) 
        throws HttpFailure, IOException;
    
    /**
     * Unregister application node from Keycloak server
     * @param deployment Keycloak deployment configuration
     * @param host Host identifier for the node
     * @throws HttpFailure If unregistration fails
     * @throws IOException If network operation fails
     */
    public static void invokeUnregisterNode(KeycloakDeployment deployment, String host) 
        throws HttpFailure, IOException;
    
    /**
     * Invoke generic client management request
     * @param deployment Keycloak deployment configuration
     * @param host Host identifier
     * @param endpointUrl Management endpoint URL
     * @throws HttpFailure If request fails
     * @throws IOException If network operation fails
     */
    public static void invokeClientManagementRequest(
        KeycloakDeployment deployment,
        String host,
        String endpointUrl
    ) throws HttpFailure, IOException;
    
    /**
     * Handle error response and throw appropriate exception
     * @param status HTTP status code
     * @param entity Response entity
     * @throws HttpFailure Always thrown with error details
     * @throws IOException If entity processing fails
     */
    public static void error(int status, HttpEntity entity) throws HttpFailure, IOException;
}

Usage Examples:

// Token refresh operation
try {
    AccessTokenResponse tokenResponse = ServerRequest.invokeRefresh(deployment, refreshToken);
    
    String newAccessToken = tokenResponse.getToken();
    String newRefreshToken = tokenResponse.getRefreshToken();
    String newIdToken = tokenResponse.getIdToken();
    int expiresIn = tokenResponse.getExpiresIn();
    
    // Update security context with new tokens
    securityContext.updateTokens(newAccessToken, newRefreshToken, newIdToken);
    
} catch (ServerRequest.HttpFailure e) {
    // Handle server error (e.g., invalid refresh token)
    logger.warn("Token refresh failed: {}", e.getMessage());
    // Redirect to re-authentication
    
} catch (IOException e) {
    // Handle network error
    logger.error("Network error during token refresh", e);
    // Retry or fallback logic
}

// Authorization code exchange
try {
    AccessTokenResponse tokenResponse = ServerRequest.invokeAccessCodeToToken(
        deployment, 
        authorizationCode, 
        redirectUri, 
        sessionId
    );
    
    // Create security context from tokens
    RefreshableKeycloakSecurityContext securityContext = 
        createSecurityContext(tokenResponse);
    
} catch (ServerRequest.HttpFailure e) {
    // Handle authorization code exchange failure
    logger.warn("Code to token exchange failed: {}", e.getMessage());
    sendOAuthError(response, "invalid_grant", e.getMessage());
}

// PKCE-enabled authorization code exchange
String codeVerifier = generateCodeVerifier();
try {
    AccessTokenResponse tokenResponse = ServerRequest.invokeAccessCodeToToken(
        deployment, 
        authorizationCode, 
        redirectUri, 
        sessionId,
        codeVerifier
    );
    
} catch (ServerRequest.HttpFailure e) {
    logger.warn("PKCE code exchange failed: {}", e.getMessage());
}

// User logout
try {
    ServerRequest.invokeLogout(deployment, refreshToken);
    logger.debug("User logged out successfully");
    
} catch (ServerRequest.HttpFailure e) {
    logger.warn("Logout request failed: {}", e.getMessage());
    // Continue with local logout even if server logout fails
    
} catch (IOException e) {
    logger.error("Network error during logout", e);
}

// Node registration for clustered applications
try {
    String hostIdentifier = InetAddress.getLocalHost().getHostName();
    ServerRequest.invokeRegisterNode(deployment, hostIdentifier);
    logger.info("Node registered with Keycloak: {}", hostIdentifier);
    
} catch (ServerRequest.HttpFailure e) {
    logger.error("Failed to register node: {}", e.getMessage());
    
} catch (IOException e) {
    logger.error("Network error during node registration", e);
}

// Node unregistration during shutdown
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    try {
        String hostIdentifier = getCurrentHostIdentifier();
        ServerRequest.invokeUnregisterNode(deployment, hostIdentifier);
        logger.info("Node unregistered from Keycloak: {}", hostIdentifier);
    } catch (Exception e) {
        logger.warn("Failed to unregister node during shutdown", e);
    }
}));

HttpClientAdapterException

Exception thrown for HTTP client adapter operations.

/**
 * Exception thrown for HTTP client adapter operations
 */
public class HttpClientAdapterException extends Exception {
    /**
     * Constructor with error message
     * @param message Error description
     */
    public HttpClientAdapterException(String message);
    
    /**
     * Constructor with error message and cause
     * @param message Error description
     * @param t Underlying cause
     */
    public HttpClientAdapterException(String message, Throwable t);
}

Usage Examples:

// Exception handling in HTTP operations
public void performKeycloakRequest(KeycloakDeployment deployment) {
    try {
        HttpClient client = deployment.getClient();
        HttpGet request = new HttpGet(deployment.getRealmInfoUrl());
        
        HttpResponse response = client.execute(request);
        if (response.getStatusLine().getStatusCode() != 200) {
            throw new HttpClientAdapterException(
                "Failed to fetch realm info: " + response.getStatusLine().getReasonPhrase()
            );
        }
        
        // Process successful response
        
    } catch (IOException e) {
        throw new HttpClientAdapterException("Network error accessing Keycloak", e);
    } catch (Exception e) {
        throw new HttpClientAdapterException("Unexpected error in Keycloak request", e);
    }
}

HTTP Configuration Patterns

SSL Configuration

// Custom SSL context with specific trust store
public SSLContext createCustomSslContext() throws Exception {
    // Load custom trust store
    KeyStore trustStore = KeyStore.getInstance("JKS");
    try (InputStream trustStoreStream = getClass().getResourceAsStream("/keycloak-truststore.jks")) {
        trustStore.load(trustStoreStream, "truststore-password".toCharArray());
    }
    
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(trustStore);
    
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
    
    return sslContext;
}

// Configure deployment with custom SSL
KeycloakDeployment deployment = new KeycloakDeployment();
HttpClient client = new HttpClientBuilder()
    .sslContext(createCustomSslContext())
    .hostnameVerification(HostnameVerificationPolicy.STRICT)
    .build();
deployment.setClient(client);

Connection Pool Configuration

// Production HTTP client configuration
public HttpClient createProductionHttpClient() {
    return new HttpClientBuilder()
        .connectionPoolSize(50)              // Total connections
        .maxPooledPerRoute(10)               // Per-route connections
        .connectionTTL(60, TimeUnit.SECONDS) // Connection reuse time
        .socketTimeout(30, TimeUnit.SECONDS) // Response timeout
        .establishConnectionTimeout(10, TimeUnit.SECONDS) // Connection timeout
        .build();
}

// Development HTTP client configuration
public HttpClient createDevelopmentHttpClient() {
    return new HttpClientBuilder()
        .disableTrustManager()               // Accept self-signed certificates
        .hostnameVerification(HostnameVerificationPolicy.ANY)
        .socketTimeout(60, TimeUnit.SECONDS) // Longer timeout for debugging
        .build();
}

Install with Tessl CLI

npx tessl i tessl/maven-org-keycloak--keycloak-adapter-core

docs

authentication.md

core-adapters.md

http-operations.md

index.md

jaas-integration.md

key-rotation.md

policy-enforcement.md

token-storage.md

utility-operations.md

tile.json