CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-keycloak--keycloak-adapter-spi

Service Provider Interface for Keycloak authentication adapters across different application server environments

Pending
Overview
Eval results
Files

session-management.mddocs/

Session Management

Comprehensive session mapping and management capabilities for correlating SSO sessions with application sessions, including user session management and request storage. These interfaces enable Keycloak adapters to maintain consistent session state across different application server environments.

Capabilities

SessionIdMapper Interface

Core interface for mapping between user session IDs, principals, and HTTP session IDs in Keycloak adapters. This enables correlation between Keycloak's SSO sessions and application-specific HTTP sessions.

import java.util.Set;

/**
 * Interface for mapping between user session IDs, principals, and HTTP session IDs
 */
public interface SessionIdMapper {
    /**
     * Checks if the mapper contains a mapping for the given HTTP session ID
     * @param id HTTP session ID
     * @return true if mapping exists, false otherwise
     */
    boolean hasSession(String id);
    
    /**
     * Clears all mappings from this mapper
     */
    void clear();
    
    /**
     * Gets all HTTP session IDs associated with the given principal
     * @param principal User principal
     * @return Set of HTTP session IDs for the principal
     */
    Set<String> getUserSessions(String principal);
    
    /**
     * Gets the HTTP session ID from the given user session ID
     * @param sso User session ID (SSO session)
     * @return HTTP session ID, or null if not found
     */
    String getSessionFromSSO(String sso);
    
    /**
     * Establishes mapping between user session ID, principal and HTTP session ID
     * @param sso User session ID (SSO session)
     * @param principal User principal
     * @param session HTTP session ID
     */
    void map(String sso, String principal, String session);
    
    /**
     * Removes all mappings for the given HTTP session ID
     * @param session HTTP session ID to remove
     */
    void removeSession(String session);
}

InMemorySessionIdMapper Class

Thread-safe in-memory implementation of SessionIdMapper using concurrent hash maps for high-performance session mapping in multi-threaded environments.

import java.util.concurrent.ConcurrentHashMap;
import java.util.Collections;
import java.util.HashSet;
import org.jboss.logging.Logger;

/**
 * In-memory implementation of SessionIdMapper that maps external principal and SSO ID
 * to internal local HTTP session ID using concurrent hash maps for thread safety
 */
public class InMemorySessionIdMapper implements SessionIdMapper {
    private static final Logger LOG = Logger.getLogger(InMemorySessionIdMapper.class.getName());
    
    /** Maps SSO session ID to HTTP session ID */
    ConcurrentHashMap<String, String> ssoToSession = new ConcurrentHashMap<>();
    
    /** Maps HTTP session ID to SSO session ID */
    ConcurrentHashMap<String, String> sessionToSso = new ConcurrentHashMap<>();
    
    /** Maps principal to set of HTTP session IDs */
    ConcurrentHashMap<String, Set<String>> principalToSession = new ConcurrentHashMap<>();
    
    /** Maps HTTP session ID to principal */
    ConcurrentHashMap<String, String> sessionToPrincipal = new ConcurrentHashMap<>();
    
    /**
     * Checks if session exists in mapper
     * @param id HTTP session ID
     * @return true if session mapping exists
     */
    public boolean hasSession(String id);
    
    /**
     * Clears all mappings
     */
    public void clear();
    
    /**
     * Gets user sessions for principal
     * @param principal User principal
     * @return Set of HTTP session IDs
     */
    public Set<String> getUserSessions(String principal);
    
    /**
     * Gets HTTP session from SSO session ID
     * @param sso SSO session ID
     * @return HTTP session ID
     */
    public String getSessionFromSSO(String sso);
    
    /**
     * Creates mapping between SSO, principal, and HTTP session
     * @param sso SSO session ID
     * @param principal User principal
     * @param session HTTP session ID
     */
    public void map(String sso, String principal, String session);
    
    /**
     * Removes session mapping
     * @param session HTTP session ID to remove
     */
    public void removeSession(String session);
}

SessionIdMapperUpdater Interface

Mechanism for updating SessionIdMapper entries with predefined strategies for direct and external update patterns.

/**
 * Interface representing a mechanism for updating SessionIdMapper entries
 */
public interface SessionIdMapperUpdater {
    /**
     * Clears all mappings from the given SessionIdMapper
     * @param idMapper SessionIdMapper to clear
     */
    void clear(SessionIdMapper idMapper);
    
    /**
     * Creates mapping between user session ID, principal and HTTP session ID
     * @param idMapper SessionIdMapper to update
     * @param sso User session ID
     * @param principal User principal
     * @param session HTTP session ID
     */
    void map(SessionIdMapper idMapper, String sso, String principal, String session);
    
    /**
     * Removes mapping for the given HTTP session ID
     * @param idMapper SessionIdMapper to update
     * @param session HTTP session ID to remove
     */
    void removeSession(SessionIdMapper idMapper, String session);
    
    /**
     * Refreshes mapping from internal source
     * @param idMapper SessionIdMapper to refresh
     * @param httpSessionId HTTP session ID to refresh
     * @return true if refresh was successful
     */
    boolean refreshMapping(SessionIdMapper idMapper, String httpSessionId);
    
    /** Direct updater that updates SessionIdMapper entries directly */
    public static final SessionIdMapperUpdater DIRECT = new SessionIdMapperUpdater() {
        @Override public void clear(SessionIdMapper idMapper) {
            idMapper.clear();
        }
        @Override public void map(SessionIdMapper idMapper, String sso, String principal, String httpSessionId) {
            idMapper.map(sso, principal, httpSessionId);
        }
        @Override public void removeSession(SessionIdMapper idMapper, String httpSessionId) {
            idMapper.removeSession(httpSessionId);
        }
        @Override public boolean refreshMapping(SessionIdMapper idMapper, String httpSessionId) {
            return false;
        }
    };
    
    /** External updater that doesn't update SessionIdMapper entries (updated by external means) */
    public static final SessionIdMapperUpdater EXTERNAL = new SessionIdMapperUpdater() {
        @Override public void clear(SessionIdMapper idMapper) { }
        @Override public void map(SessionIdMapper idMapper, String sso, String principal, String httpSessionId) { }
        @Override public void removeSession(SessionIdMapper idMapper, String httpSessionId) { }
        @Override public boolean refreshMapping(SessionIdMapper idMapper, String httpSessionId) { return false; }
    };
}

UserSessionManagement Interface

Interface for managing user sessions with capabilities to log out all sessions or specific HTTP sessions.

import java.util.List;

/**
 * Interface for managing user sessions
 */
public interface UserSessionManagement {
    /**
     * Logs out all sessions for the current user
     */
    void logoutAll();
    
    /**
     * Logs out specific HTTP sessions by their IDs
     * @param ids List of HTTP session IDs to log out
     */
    void logoutHttpSessions(List<String> ids);
}

AdapterSessionStore Interface

Interface for storing and restoring HTTP requests during authentication flows, enabling request preservation across authentication redirects.

/**
 * Interface for storing and restoring HTTP requests during authentication flows
 */
public interface AdapterSessionStore {
    /**
     * Saves the current HTTP request for later restoration
     */
    void saveRequest();
    
    /**
     * Restores a previously saved HTTP request
     * @return true if request was successfully restored, false otherwise
     */
    boolean restoreRequest();
}

Usage Examples

Basic Session Mapping

import org.keycloak.adapters.spi.*;

// Create session mapper
SessionIdMapper sessionMapper = new InMemorySessionIdMapper();

// Map SSO session to HTTP session
String ssoSessionId = "keycloak-sso-123";
String principal = "user@example.com";  
String httpSessionId = "JSESSION-456";

sessionMapper.map(ssoSessionId, principal, httpSessionId);

// Check if session exists
if (sessionMapper.hasSession(httpSessionId)) {
    // Get SSO session from HTTP session
    String ssoId = sessionMapper.getSessionFromSSO(ssoSessionId);
    
    // Get all HTTP sessions for a user
    Set<String> userSessions = sessionMapper.getUserSessions(principal);
}

// Clean up when session ends
sessionMapper.removeSession(httpSessionId);

Session Updater Usage

// Use direct updater strategy
SessionIdMapperUpdater updater = SessionIdMapperUpdater.DIRECT;
SessionIdMapper mapper = new InMemorySessionIdMapper();

// Create mapping via updater
updater.map(mapper, "sso-123", "user@example.com", "http-456");

// Refresh mapping if needed
boolean refreshed = updater.refreshMapping(mapper, "http-456");

// Clean up via updater
updater.removeSession(mapper, "http-456");

User Session Management

public class MyUserSessionManager implements UserSessionManagement {
    private final SessionIdMapper sessionMapper;
    
    public MyUserSessionManager(SessionIdMapper sessionMapper) {
        this.sessionMapper = sessionMapper;
    }
    
    @Override
    public void logoutAll() {
        // Log out all sessions for current user
        String currentPrincipal = getCurrentPrincipal();
        Set<String> userSessions = sessionMapper.getUserSessions(currentPrincipal);
        
        for (String sessionId : userSessions) {
            invalidateHttpSession(sessionId);
            sessionMapper.removeSession(sessionId);
        }
    }
    
    @Override
    public void logoutHttpSessions(List<String> ids) {
        // Log out specific sessions
        for (String sessionId : ids) {
            invalidateHttpSession(sessionId);
            sessionMapper.removeSession(sessionId);
        }
    }
    
    private void invalidateHttpSession(String sessionId) {
        // Platform-specific session invalidation
    }
    
    private String getCurrentPrincipal() {
        // Get current user principal
        return "user@example.com";
    }
}

Request Storage During Authentication

public class MyAdapterSessionStore implements AdapterSessionStore {
    private final HttpServletRequest request;
    private final HttpSession session;
    
    public MyAdapterSessionStore(HttpServletRequest request) {
        this.request = request;
        this.session = request.getSession();
    }
    
    @Override
    public void saveRequest() {
        // Save request URL and parameters for post-auth redirect
        session.setAttribute("saved.request.url", request.getRequestURL().toString());
        session.setAttribute("saved.request.method", request.getMethod());
        
        // Save request parameters
        Map<String, String[]> params = request.getParameterMap();
        session.setAttribute("saved.request.params", params);
    }
    
    @Override
    public boolean restoreRequest() {
        String savedUrl = (String) session.getAttribute("saved.request.url");
        if (savedUrl != null) {
            // Restore request state and redirect
            session.removeAttribute("saved.request.url");
            session.removeAttribute("saved.request.method");
            session.removeAttribute("saved.request.params");
            
            // Perform redirect to saved URL
            redirectToSavedUrl(savedUrl);
            return true;
        }
        return false;
    }
    
    private void redirectToSavedUrl(String url) {
        // Platform-specific redirect implementation
    }
}

Install with Tessl CLI

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

docs

authentication.md

http-facade.md

index.md

session-management.md

tile.json