or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

auto-configuration.mdheader-theme-resolution.mdindex.mdservice-theme-resolution.mdtheme-resolution.mdtheme-sources.md
tile.json

tessl/maven-org-apereo-cas--cas-server-support-themes

Apereo CAS Web Application Themes Support - Provides comprehensive theme resolution and management capabilities for the Central Authentication Service

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/org.apereo.cas/cas-server-support-themes@7.2.x

To install, run

npx @tessl/cli install tessl/maven-org-apereo-cas--cas-server-support-themes@7.2.0

index.mddocs/

CAS Themes Support

The CAS Themes Support library provides comprehensive theme management capabilities for the Central Authentication Service (CAS). It enables dynamic theme selection based on multiple strategies including registered service configurations, browser cookies, HTTP session attributes, request headers, and fixed configuration settings.

Package Information

  • Package Name: org.apereo.cas:cas-server-support-themes
  • Package Type: maven
  • Language: Java
  • Installation: Add to your Gradle or Maven dependencies

Gradle:

implementation 'org.apereo.cas:cas-server-support-themes:7.2.4'

Maven:

<dependency>
    <groupId>org.apereo.cas</groupId>
    <artifactId>cas-server-support-themes</artifactId>
    <version>7.2.4</version>
</dependency>

Core Imports

// Main Configuration
import org.apereo.cas.config.CasThemesAutoConfiguration;

// Theme Sources
import org.apereo.cas.services.web.DefaultCasThemeSource;
import org.apereo.cas.services.web.AggregateCasThemeSource;
import org.apereo.cas.services.web.CasThemeResourceBundleMessageSource;

// Theme Resolvers
import org.apereo.cas.services.web.ChainingThemeResolver;
import org.apereo.cas.services.web.RegisteredServiceThemeResolver;
import org.apereo.cas.services.web.RequestHeaderThemeResolver;

// Configuration Properties
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.configuration.model.support.themes.ThemeProperties;
import org.apereo.cas.configuration.model.core.web.view.ViewProperties;

// CAS Services API (for service-based theme resolution)
import org.apereo.cas.services.ServicesManager;
import org.apereo.cas.services.WebBasedRegisteredService;
import org.apereo.cas.authentication.AuthenticationServiceSelectionPlan;
import org.apereo.cas.authentication.principal.Service;

// Spring Framework Types
import org.springframework.ui.context.ThemeSource;
import org.springframework.web.servlet.ThemeResolver;
import org.springframework.web.servlet.theme.AbstractThemeResolver;
import org.springframework.ui.context.support.ResourceBundleThemeSource;

Basic Usage

import org.apereo.cas.services.web.ChainingThemeResolver;
import org.apereo.cas.services.web.DefaultCasThemeSource;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.springframework.web.servlet.theme.CookieThemeResolver;
import org.springframework.web.servlet.theme.SessionThemeResolver;

// Basic theme source setup
CasConfigurationProperties casProperties = // ... obtained from Spring context
DefaultCasThemeSource themeSource = new DefaultCasThemeSource(casProperties);

// Create a chaining theme resolver with multiple strategies
ChainingThemeResolver chainResolver = new ChainingThemeResolver();
chainResolver.setDefaultThemeName("cas-theme-default");

// Add cookie-based theme resolution
CookieThemeResolver cookieResolver = new CookieThemeResolver();
cookieResolver.setDefaultThemeName("cas-theme-default");
chainResolver.addResolver(cookieResolver);

// Add session-based theme resolution  
SessionThemeResolver sessionResolver = new SessionThemeResolver();
sessionResolver.setDefaultThemeName("cas-theme-default");
chainResolver.addResolver(sessionResolver);

// Resolve theme from HTTP request
String themeName = chainResolver.resolveThemeName(request);
System.out.println("Resolved theme: " + themeName);

// Get theme resources
Theme theme = themeSource.getTheme(themeName);
MessageSource messageSource = theme.getMessageSource();
String welcomeMessage = messageSource.getMessage("login.welcome", null, 
    "Welcome", request.getLocale());

Architecture

The CAS Themes Support library is built around several key components:

  • Auto-Configuration: Spring Boot auto-configuration (CasThemesAutoConfiguration) that automatically sets up theme resolution based on properties
  • Theme Sources: Implementations that load theme properties and resources (DefaultCasThemeSource, AggregateCasThemeSource)
  • Theme Resolvers: Chain of responsibility pattern for theme resolution using multiple strategies (ChainingThemeResolver)
  • Resolution Strategies: Individual resolvers for different theme selection methods (cookie, session, service-based, header-based)
  • Resource Management: Static resource handling with caching and versioning support

Capabilities

Auto-Configuration

Spring Boot auto-configuration that sets up theme resolution beans automatically based on CAS configuration properties.

@AutoConfiguration
@ConditionalOnFeatureEnabled(feature = CasFeatureModule.FeatureCatalog.Thymeleaf)
public class CasThemesAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean(name = "casThemeSource")
    @RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
    public ThemeSource themeSource(CasConfigurationProperties casProperties);
    
    @Bean
    @ConditionalOnMissingBean(name = "casThemeResolver")
    @RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
    public ThemeResolver themeResolver(
        ObjectProvider<CasConfigurationProperties> casProperties,
        ObjectProvider<AuthenticationServiceSelectionPlan> authenticationRequestServiceSelectionStrategies,
        ObjectProvider<ServicesManager> servicesManager);
}

Auto-Configuration

Theme Sources

Theme source implementations that load and manage theme properties and resources from various locations.

public class DefaultCasThemeSource extends ResourceBundleThemeSource {
    public DefaultCasThemeSource(CasConfigurationProperties casProperties);
    
    @Override
    protected MessageSource createMessageSource(@Nonnull String basename);
}

public class AggregateCasThemeSource extends ResourceBundleThemeSource {
    public AggregateCasThemeSource(CasConfigurationProperties casProperties);
    
    @Override  
    protected MessageSource createMessageSource(@Nonnull String basename);
}

Theme Sources

Theme Resolution

Chain-based theme resolution system that evaluates multiple resolution strategies in priority order.

public class ChainingThemeResolver extends AbstractThemeResolver {
    public ChainingThemeResolver addResolver(ThemeResolver r);
    
    @Override
    public String resolveThemeName(@Nonnull HttpServletRequest httpServletRequest);
    
    @Override
    public void setThemeName(@Nonnull HttpServletRequest httpServletRequest, 
                           HttpServletResponse httpServletResponse, String s);
}

Theme Resolution

Service-Based Theme Resolution

Advanced theme resolution based on registered service configurations, supporting Groovy scripts and HTTP URLs for dynamic theme selection.

public class RegisteredServiceThemeResolver extends AbstractThemeResolver {
    public RegisteredServiceThemeResolver(
        ObjectProvider<ServicesManager> servicesManager,
        ObjectProvider<AuthenticationServiceSelectionPlan> authenticationRequestServiceSelectionStrategies,
        ObjectProvider<CasConfigurationProperties> casProperties);
    
    @Override
    public String resolveThemeName(@Nonnull HttpServletRequest request);
}

Service-Based Theme Resolution

Header-Based Theme Resolution

Simple theme resolution that extracts theme names from HTTP request headers.

public class RequestHeaderThemeResolver extends AbstractThemeResolver {
    public RequestHeaderThemeResolver(String themeHeaderName);
    
    @Override
    public String resolveThemeName(HttpServletRequest request);
}

Header-Based Theme Resolution

Types

// Spring Framework Types
interface ThemeSource {
    Theme getTheme(String themeName);
}

interface Theme {
    String getName();
    MessageSource getMessageSource();
}

interface ThemeResolver {
    String resolveThemeName(HttpServletRequest request);
    void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName);
}

abstract class AbstractThemeResolver implements ThemeResolver {
    String getDefaultThemeName();
    void setDefaultThemeName(String defaultThemeName);
}

class ResourceBundleThemeSource implements ThemeSource {
    String getBasenamePrefix();
    void setBasenamePrefix(String basenamePrefix);
    protected MessageSource createMessageSource(String basename);
}

// CAS Services Types
interface Service {
    String getId();
}

interface ServicesManager {
    RegisteredService findServiceBy(Service service);
}

class WebBasedRegisteredService extends BaseRegisteredService {
    String getTheme();
    void setTheme(String theme);
    RegisteredServiceAccessStrategy getAccessStrategy();
}

interface AuthenticationServiceSelectionPlan {
    Service resolveService(Service service);
}

// CAS Configuration Types  
class CasConfigurationProperties {
    ThemeProperties getTheme();
    ViewProperties getView();
    TgcProperties getTgc();
}

class ThemeProperties {
    String getDefaultThemeName();    // Default: "cas-theme-default"
    String getParamName();          // Default: "theme"
}

class ViewProperties {
    List<String> getTemplatePrefixes();
    ThemeSourceTypes getThemeSourceType();  // Default: DEFAULT
    
    enum ThemeSourceTypes {
        DEFAULT,     // Use DefaultCasThemeSource
        AGGREGATE    // Use AggregateCasThemeSource
    }
}

class TgcProperties {
    String getDomain();
    boolean isHttpOnly();
    String getMaxAge();
    String getPath();
    boolean isSecure();
}

// Spring Web Types
class HttpServletRequest {
    String getHeader(String name);
    String getQueryString();
    Locale getLocale();
    void setAttribute(String name, Object value);
}

class HttpServletResponse {
    // HTTP response methods
}

interface MessageSource {
    String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
}

class StaticMessageSource implements MessageSource {
    void addMessage(String code, Locale locale, String msg);
}