Apereo CAS Core Utilities - A comprehensive utility library providing functional programming constructs, encryption utilities, configuration helpers, and core infrastructure components for the Central Authentication Service framework
—
Deep Spring Framework integration providing application context management, conditional beans, configuration properties, Spring Boot support, and custom conditions for CAS applications.
Central provider for Spring application context access and bean management throughout the CAS system.
public class ApplicationContextProvider implements ApplicationContextAware {
// Core context access
public static ApplicationContext getApplicationContext();
public static ConfigurableApplicationContext getConfigurableApplicationContext();
// ApplicationContextAware implementation
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException;
// Static context management
public static void holdApplicationContext(ApplicationContext ctx);
// Bean injection and processing
public static void processBeanInjections(Object bean);
// Bean registration
public static <T> T registerBeanIntoApplicationContext(
ApplicationContext applicationContext,
T object,
String name
);
public static <T> T registerBeanIntoApplicationContext(
ConfigurableApplicationContext applicationContext,
T object,
String name
);
// Bean retrieval utilities
public static <T> Optional<T> getBean(String name, Class<T> clazz);
public static <T> Optional<T> getBean(Class<T> clazz);
// CAS-specific utilities
public static Optional<CasConfigurationProperties> getCasConfigurationProperties();
public static Optional<ScriptResourceCacheManager<String, ExecutableCompiledScript>>
getScriptResourceCacheManager();
public static Optional<MessageSanitizer> getMessageSanitizer();
}Basic application context usage:
@Component
public class CasServiceImpl implements CasService {
public void performOperation() {
// Access application context
ApplicationContext context = ApplicationContextProvider.getApplicationContext();
// Get beans by type
Optional<UserService> userService = ApplicationContextProvider.getBean(UserService.class);
// Get beans by name and type
Optional<CacheManager> cacheManager =
ApplicationContextProvider.getBean("cacheManager", CacheManager.class);
// Access CAS configuration
Optional<CasConfigurationProperties> config =
ApplicationContextProvider.getCasConfigurationProperties();
if (config.isPresent()) {
processWithConfiguration(config.get());
}
}
public void registerDynamicBean() {
// Register beans at runtime
MyDynamicService service = new MyDynamicService();
ApplicationContextProvider.registerBeanIntoApplicationContext(
ApplicationContextProvider.getConfigurableApplicationContext(),
service,
"dynamicService"
);
}
}Bean injection in non-Spring managed classes:
public class NonSpringManagedClass {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
public NonSpringManagedClass() {
// Inject Spring dependencies
ApplicationContextProvider.processBeanInjections(this);
}
public boolean authenticate(String username, String password) {
User user = userRepository.findByUsername(username);
return user != null && passwordEncoder.matches(password, user.getPasswordHash());
}
}Abstract base for CAS application banners displayed during startup.
public abstract class AbstractCasBanner implements Banner {
// Banner configuration
protected String title;
protected String version;
protected String description;
// Banner interface implementation
@Override
public void printBanner(Environment environment,
Class<?> sourceClass,
PrintStream printStream);
// Template method for customization
protected abstract String getBannerText();
protected String getTitle();
protected String getVersion();
protected String getDescription();
}Concrete banner implementations for CAS applications.
public class CasBanner extends AbstractCasBanner {
public CasBanner();
@Override
protected String getBannerText();
}
public class DefaultCasBanner extends AbstractCasBanner {
public DefaultCasBanner();
@Override
protected String getBannerText();
}Abstract servlet initializer for CAS Spring Boot applications.
public abstract class AbstractCasSpringBootServletInitializer
extends SpringBootServletInitializer {
// Servlet initialization
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application);
// Template methods for customization
protected abstract Class<?>[] getConfigurationClasses();
protected String[] getActiveProfiles();
protected Properties getDefaultProperties();
}Custom banner implementation:
@Component
public class CustomCasBanner extends AbstractCasBanner {
public CustomCasBanner() {
this.title = "My CAS Server";
this.version = "1.0.0";
this.description = "Custom CAS Implementation";
}
@Override
protected String getBannerText() {
return """
╔════════════════════════════════════╗
║ MY CAS SERVER ║
║ v1.0.0 ║
╚════════════════════════════════════╝
""";
}
}
@SpringBootApplication
public class MyCasApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyCasApplication.class);
app.setBanner(new CustomCasBanner());
app.run(args);
}
}Servlet initializer for WAR deployment:
public class CasWebApplicationInitializer extends AbstractCasSpringBootServletInitializer {
@Override
protected Class<?>[] getConfigurationClasses() {
return new Class<?>[] {
CasWebApplication.class,
CasSecurityConfiguration.class,
CasServicesConfiguration.class
};
}
@Override
protected String[] getActiveProfiles() {
return new String[] { "production", "ssl" };
}
@Override
protected Properties getDefaultProperties() {
Properties props = new Properties();
props.setProperty("server.port", "8443");
props.setProperty("server.ssl.enabled", "true");
return props;
}
}@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(CasFeatureEnabledCondition.class)
public @interface ConditionalOnFeatureEnabled {
// Feature name to check
String feature();
// Module name (optional)
String module() default "";
// Enabled by default
boolean enabledByDefault() default true;
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(CasFeatureEnabledCondition.class)
public @interface ConditionalOnFeaturesEnabled {
// Multiple features (AND logic)
ConditionalOnFeatureEnabled[] value();
}@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(MatchingHostnameCondition.class)
public @interface ConditionalOnMatchingHostname {
// Hostname patterns to match
String[] value();
// Use regex matching
boolean regex() default false;
}@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(CasGraalVMNativeImageDisabledCondition.class)
public @interface ConditionalOnMissingGraalVMNativeImage {
}Feature-based conditional configuration:
@Configuration
public class ConditionalConfiguration {
@Bean
@ConditionalOnFeatureEnabled(feature = "multifactor-authentication")
public MultiFactorAuthenticationProvider mfaProvider() {
return new DefaultMultiFactorAuthenticationProvider();
}
@Bean
@ConditionalOnFeaturesEnabled({
@ConditionalOnFeatureEnabled(feature = "ldap"),
@ConditionalOnFeatureEnabled(feature = "authentication")
})
public LdapAuthenticationHandler ldapAuthHandler() {
return new LdapAuthenticationHandler();
}
@Bean
@ConditionalOnMatchingHostname({"*.example.com", "cas-prod-*"})
public ProductionSecurityConfiguration prodSecurityConfig() {
return new ProductionSecurityConfiguration();
}
@Bean
@ConditionalOnMissingGraalVMNativeImage
public ReflectionBasedService reflectionService() {
// Only available in JVM mode, not in native image
return new ReflectionBasedService();
}
}Supplier interface for conditional bean creation with enhanced features.
public interface BeanSupplier<T> extends Supplier<T> {
// Enhanced supply methods
T supply();
T supply(Supplier<T> defaultSupplier);
// Conditional operations
BeanSupplier<T> ifAvailable();
BeanSupplier<T> ifMissing();
BeanSupplier<T> when(BeanCondition condition);
// Factory methods
static <T> BeanSupplier<T> of(Supplier<T> supplier);
static <T> BeanSupplier<T> ofBean(Class<T> beanType);
static <T> BeanSupplier<T> ofBean(String beanName, Class<T> beanType);
}Container interface for managing bean collections.
public interface BeanContainer<T> {
// Container operations
Collection<T> toCollection();
List<T> toList();
Set<T> toSet();
// Filtering operations
BeanContainer<T> filter(Predicate<T> predicate);
<R> BeanContainer<R> map(Function<T, R> mapper);
// Conditional operations
BeanContainer<T> ifAvailable();
BeanContainer<T> ifNotEmpty();
// Factory methods
static <T> BeanContainer<T> of(Collection<T> beans);
static <T> BeanContainer<T> ofType(Class<T> beanType);
}Advanced bean management:
@Service
public class DynamicBeanService {
public void configureDynamicBeans() {
// Conditional bean supply
AuthenticationHandler handler = BeanSupplier
.ofBean("ldapAuthHandler", AuthenticationHandler.class)
.ifAvailable()
.supply(() -> new DefaultAuthenticationHandler());
// Bean container operations
List<AuthenticationHandler> handlers = BeanContainer
.ofType(AuthenticationHandler.class)
.filter(h -> h.supports(UsernamePasswordCredential.class))
.toList();
// Conditional bean creation
CacheManager cacheManager = BeanSupplier
.ofBean(CacheManager.class)
.when(environment -> environment.getProperty("cache.enabled", Boolean.class, false))
.supply(() -> new InMemoryCacheManager());
}
}Direct object provider implementation for dependency injection.
public class DirectObjectProvider<T> implements ObjectProvider<T> {
public DirectObjectProvider(T object);
@Override
public T getObject() throws BeansException;
@Override
public T getObject(Object... args) throws BeansException;
@Override
public T getIfAvailable() throws BeansException;
@Override
public T getIfUnique() throws BeansException;
@Override
public Stream<T> stream();
@Override
public Iterator<T> iterator();
}SpEL (Spring Expression Language) value resolver for dynamic property resolution.
public class SpringExpressionLanguageValueResolver {
// Expression evaluation
public Object evaluate(String expression, Map<String, Object> variables);
public <T> T evaluate(String expression, Class<T> resultType);
public <T> T evaluate(String expression,
Map<String, Object> variables,
Class<T> resultType);
// Template-based evaluation
public String evaluateTemplate(String template, Map<String, Object> variables);
// Utility methods
public boolean isExpression(String value);
public static SpringExpressionLanguageValueResolver getInstance();
}Security context utilities for authentication and authorization operations.
@UtilityClass
public class SecurityContextUtils {
// Authentication access
public static Authentication getAuthentication();
public static Optional<Authentication> getCurrentAuthentication();
// Principal access
public static Object getPrincipal();
public static <T> T getPrincipal(Class<T> type);
public static String getUsername();
// Authority checking
public static boolean hasRole(String role);
public static boolean hasAuthority(String authority);
public static boolean hasAnyRole(String... roles);
public static boolean hasAnyAuthority(String... authorities);
// Context management
public static void setAuthentication(Authentication authentication);
public static void clearContext();
}SpEL integration for dynamic configuration:
@Component
public class DynamicConfigurationService {
private final SpringExpressionLanguageValueResolver spelResolver;
public DynamicConfigurationService() {
this.spelResolver = SpringExpressionLanguageValueResolver.getInstance();
}
public String resolveConfigValue(String configExpression, User user) {
Map<String, Object> context = Map.of(
"user", user,
"env", System.getenv(),
"props", System.getProperties()
);
if (spelResolver.isExpression(configExpression)) {
return spelResolver.evaluate(configExpression, context, String.class);
}
return configExpression;
}
public boolean evaluateCondition(String condition, HttpServletRequest request) {
Map<String, Object> context = Map.of(
"request", request,
"headers", Collections.list(request.getHeaderNames()),
"params", request.getParameterMap()
);
return spelResolver.evaluate(condition, context, Boolean.class);
}
}Security context operations:
@RestController
public class SecureApiController {
@GetMapping("/api/user-info")
public ResponseEntity<?> getUserInfo() {
// Get current authentication
Optional<Authentication> auth = SecurityContextUtils.getCurrentAuthentication();
if (auth.isEmpty()) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
// Get username
String username = SecurityContextUtils.getUsername();
// Check authorities
if (SecurityContextUtils.hasRole("USER")) {
return ResponseEntity.ok(Map.of("username", username, "role", "user"));
} else if (SecurityContextUtils.hasAuthority("ADMIN")) {
return ResponseEntity.ok(Map.of("username", username, "role", "admin"));
}
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
@PostMapping("/api/admin-action")
public ResponseEntity<?> performAdminAction() {
// Check multiple roles
if (!SecurityContextUtils.hasAnyRole("ADMIN", "SUPER_USER")) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
// Perform admin action
String username = SecurityContextUtils.getUsername();
log.info("Admin action performed by: {}", username);
return ResponseEntity.ok("Action completed");
}
}public final class Converters {
// String converters
public static class StringToZonedDateTimeConverter
implements Converter<String, ZonedDateTime>;
public static class StringToLocalDateTimeConverter
implements Converter<String, LocalDateTime>;
// Collection converters
public static class StringToCollectionConverter
implements Converter<String, Collection>;
// Custom object converters
public static class StringToBeanConverter<T>
implements Converter<String, T>;
}Custom converter registration:
@Configuration
public class ConverterConfiguration {
@Bean
public ConversionService conversionService() {
DefaultConversionService service = new DefaultConversionService();
// Register custom converters
service.addConverter(new Converters.StringToZonedDateTimeConverter());
service.addConverter(new Converters.StringToLocalDateTimeConverter());
service.addConverter(new Converters.StringToCollectionConverter());
return service;
}
}This comprehensive Spring integration provides the foundation for building scalable, configurable CAS applications with full Spring Framework support, conditional bean creation, and advanced application context management.
Install with Tessl CLI
npx tessl i tessl/maven-org-apereo-cas--cas-server-core-util-api