CtrlK
BlogDocsLog inGet started
Tessl Logo

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

Pending
Overview
Eval results
Files

service-theme-resolution.mddocs/

Service-Based Theme Resolution

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

Capabilities

RegisteredServiceThemeResolver

Theme resolver that determines theme based on registered service configuration with support for dynamic theme determination.

/**
 * Theme resolver that determines theme based on registered service configuration
 * Supports static themes, Groovy scripts, and HTTP URLs for dynamic theme selection
 */
public class RegisteredServiceThemeResolver extends AbstractThemeResolver {
    
    /**
     * Constructor with required dependencies
     * @param servicesManager CAS services manager for service lookup
     * @param authenticationRequestServiceSelectionStrategies Service selection strategies
     * @param casProperties CAS configuration properties
     */
    public RegisteredServiceThemeResolver(
        ObjectProvider<ServicesManager> servicesManager,
        ObjectProvider<AuthenticationServiceSelectionPlan> authenticationRequestServiceSelectionStrategies,
        ObjectProvider<CasConfigurationProperties> casProperties);
    
    /**
     * Resolves theme based on service configuration
     * @param request HTTP request containing service parameter
     * @return Theme name from service configuration, or default theme
     */
    @Override
    public String resolveThemeName(@Nonnull HttpServletRequest request);
    
    /**
     * No-op implementation for theme setting
     * @param request HTTP request
     * @param response HTTP response
     * @param themeName Theme name
     */
    @Override
    public void setThemeName(@Nonnull HttpServletRequest request, 
                           HttpServletResponse response, String themeName);
    
    /**
     * Determines theme name from service configuration
     * @param request HTTP request
     * @param service Resolved service
     * @param registeredService Registered service configuration
     * @return Theme name or default theme
     */
    protected String determineThemeNameToChoose(HttpServletRequest request,
                                              Service service,
                                              WebBasedRegisteredService registeredService);
    
    /**
     * Executes Groovy script to determine theme name
     * @param request HTTP request
     * @param service Service requesting authentication
     * @param registeredService Registered service configuration
     * @param resource Groovy script resource
     * @return Theme name from script execution
     */
    protected String determineThemeFromGroovyResource(HttpServletRequest request,
                                                    Service service,
                                                    WebBasedRegisteredService registeredService,
                                                    AbstractResource resource);
    
    /**
     * Stores theme name as request attribute for later use
     * @param request HTTP request
     * @param themeName Theme name to remember
     * @return The theme name that was stored
     */
    protected String rememberThemeName(HttpServletRequest request, String themeName);
    
    /**
     * Stores default theme name as request attribute
     * @param request HTTP request
     * @return The default theme name that was stored
     */
    protected String rememberThemeName(HttpServletRequest request);
    
    /**
     * Resolves theme for service using Spring expression evaluation
     * @param registeredService Service configuration containing theme property
     * @param request HTTP request for context
     * @return Resolved theme name or null if not found
     */
    protected String resolveThemeForService(WebBasedRegisteredService registeredService,
                                          HttpServletRequest request);
}

Usage Examples:

import org.apereo.cas.services.web.RegisteredServiceThemeResolver;
import org.apereo.cas.services.ServicesManager;

// Create service theme resolver
RegisteredServiceThemeResolver resolver = new RegisteredServiceThemeResolver(
    servicesManagerProvider,
    serviceSelectionPlanProvider, 
    casPropertiesProvider);
resolver.setDefaultThemeName("default");

// Service configuration determines theme
String theme = resolver.resolveThemeName(request);

Theme Configuration Methods

Static Theme Names

Simple static theme name in service configuration:

{
  "serviceId": "https://myapp.example.com/**",
  "name": "My Application",
  "theme": "corporate"
}

Spring Expression Language

Dynamic theme using Spring EL expressions:

{
  "serviceId": "https://myapp.example.com/**", 
  "name": "My Application",
  "theme": "#{request.getHeader('X-Client-Type') == 'mobile' ? 'mobile' : 'desktop'}"
}

Groovy Scripts

Groovy script for complex theme logic:

{
  "serviceId": "https://myapp.example.com/**",
  "name": "My Application", 
  "theme": "file:/etc/cas/themes/theme-selector.groovy"
}

Example Groovy script:

// theme-selector.groovy
def userAgent = request.getHeader("User-Agent")
def clientId = request.getParameter("client_id")

if (userAgent?.contains("Mobile")) {
    return "mobile"
} else if (clientId == "admin-portal") {
    return "admin"
} else {
    return "default"
}

HTTP URL Endpoints

HTTP endpoint that returns theme name:

{
  "serviceId": "https://myapp.example.com/**",
  "name": "My Application",
  "theme": "https://config.example.com/theme?service=${service.id}"
}

Example HTTP response:

corporate-theme

Resolution Process

  1. Service Extraction: Extracts service from request context using WebUtils
  2. Service Resolution: Uses AuthenticationServiceSelectionPlan to resolve service
  3. Service Lookup: Finds registered service using ServicesManager
  4. Access Check: Verifies service access is allowed
  5. Theme Determination: Evaluates theme configuration based on type:
    • File Resource: Executes as Groovy script
    • URL Resource: Makes HTTP GET request
    • String Value: Evaluates as Spring expression
  6. Theme Validation: Validates theme exists in template prefixes or resource bundles
  7. Result Storage: Stores resolved theme in request attributes

Groovy Script Context

Groovy scripts receive the following variables:

// Available variables in Groovy theme scripts
service              // org.apereo.cas.authentication.principal.Service
registeredService    // org.apereo.cas.services.WebBasedRegisteredService  
queryString         // String - HTTP query string
headers             // Map<String, String> - HTTP headers
logger              // org.slf4j.Logger - For logging

Example advanced Groovy script:

import java.time.LocalTime

def now = LocalTime.now()
def userAgent = headers.get("User-Agent")

// Business hours theme (9 AM - 5 PM)
if (now.isAfter(LocalTime.of(9, 0)) && now.isBefore(LocalTime.of(17, 0))) {
    logger.info("Using business hours theme for service: {}", service.id)
    return "business"
}

// Mobile detection
if (userAgent?.toLowerCase()?.contains("mobile")) {
    logger.info("Using mobile theme for service: {}", service.id)
    return "mobile"
}

// Default theme
logger.info("Using default theme for service: {}", service.id)
return "default"

HTTP URL Theme Resolution

For HTTP URL theme endpoints:

  • Method: GET request
  • Parameters: service parameter with service ID
  • Response: Plain text theme name
  • Timeout: Configurable HTTP timeout
  • Error Handling: Falls back to default theme on HTTP errors
// Example HTTP request made by resolver:
GET https://config.example.com/theme?service=https://myapp.example.com/login
Accept: text/plain

// Expected response:
corporate-dark

Theme Validation

The resolver validates themes exist before returning them:

  1. Template Prefix Search: Checks if {theme}.properties exists in template prefixes
  2. Resource Bundle Search: Uses ResourceBundle.getBundle() to verify theme
  3. Fallback: Returns default theme if validation fails

Error Handling

Comprehensive error handling for all theme determination methods:

  • Service Not Found: Returns default theme
  • Access Denied: Returns default theme
  • Groovy Script Errors: Logged, returns default theme
  • HTTP Errors: Logged, returns default theme
  • Expression Errors: Logged, returns default theme
  • Theme Validation Failures: Logged, returns default theme

Performance Considerations

  • Script Caching: Groovy scripts are cached using CAS script resource cache
  • HTTP Caching: No built-in HTTP response caching
  • Service Lookup: Cached by ServicesManager implementation
  • Request Attributes: Theme stored in request for reuse within request scope

Install with Tessl CLI

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

docs

auto-configuration.md

header-theme-resolution.md

index.md

service-theme-resolution.md

theme-resolution.md

theme-sources.md

tile.json