CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apereo-cas--cas-server-core-webflow-mfa-api

Core API for multifactor authentication webflow configuration in Apereo CAS providing interfaces and base classes for MFA provider integration

Pending
Overview
Eval results
Files

authentication-components.mddocs/

Authentication Components

Core authentication and provider selection logic including selectors, resolvers, and transaction management components. These components handle the orchestration of MFA providers, authentication context management, and provider selection strategies.

Capabilities

MultifactorAuthenticationProviderSelector Components

Components responsible for selecting appropriate MFA providers from available options based on various criteria.

RankedMultifactorAuthenticationProviderSelector

Selects MFA providers based on ranking/priority order.

/**
 * Selects MFA providers based on ranking/priority order
 */
public class RankedMultifactorAuthenticationProviderSelector 
    implements MultifactorAuthenticationProviderSelector {
    
    /**
     * Constructor
     */
    public RankedMultifactorAuthenticationProviderSelector();
    
    /**
     * Resolve appropriate MFA provider from available providers
     * @param providers Collection of available MFA providers
     * @param service Service being accessed (can be null)
     * @param principal Principal requesting authentication
     * @return Selected MultifactorAuthenticationProvider or null if none suitable
     */
    @Override
    public MultifactorAuthenticationProvider resolve(
        Collection<MultifactorAuthenticationProvider> providers,
        RegisteredService service,
        Principal principal);
    
    /**
     * Select multifactor authentication provider for service
     * @param service Service being accessed
     * @param providers List of available providers
     * @return Selected provider or null
     */
    protected MultifactorAuthenticationProvider selectMultifactorAuthenticationProvider(
        RegisteredService service,
        List<MultifactorAuthenticationProvider> providers);
}

ChainingMultifactorAuthenticationProviderSelector

Creates chaining MFA providers when multiple providers are available.

/**
 * Creates chaining MFA providers when multiple providers are available
 */
public class ChainingMultifactorAuthenticationProviderSelector 
    implements MultifactorAuthenticationProviderSelector {
    
    /**
     * Constructor
     * @param applicationContext Spring application context
     * @param failureModeEvaluator Evaluator for handling failure modes
     */
    public ChainingMultifactorAuthenticationProviderSelector(
        ConfigurableApplicationContext applicationContext,
        MultifactorAuthenticationFailureModeEvaluator failureModeEvaluator);
    
    /**
     * Resolve chaining provider from available providers
     * @param providers Collection of available MFA providers
     * @param service Service being accessed
     * @param principal Principal requesting authentication
     * @return Chaining provider or selected single provider
     */
    @Override
    public MultifactorAuthenticationProvider resolve(
        Collection<MultifactorAuthenticationProvider> providers,
        RegisteredService service,
        Principal principal);
    
    /**
     * Select multifactor authentication provider for service (protected method)
     * @param service Service being accessed
     * @param providers List of available providers
     * @return Selected provider
     */
    protected MultifactorAuthenticationProvider selectMultifactorAuthenticationProvider(
        RegisteredService service,
        List<MultifactorAuthenticationProvider> providers);
}

GroovyScriptMultifactorAuthenticationProviderSelector

MFA provider selector that uses Groovy scripts for custom selection logic.

/**
 * MFA provider selector using Groovy scripts for custom selection logic
 */
public class GroovyScriptMultifactorAuthenticationProviderSelector 
    implements MultifactorAuthenticationProviderSelector {
    
    /**
     * Constructor
     * @param groovyResource Resource containing the Groovy script
     */
    public GroovyScriptMultifactorAuthenticationProviderSelector(Resource groovyResource);
    
    /**
     * Resolve provider using Groovy script logic
     * @param providers Collection of available MFA providers
     * @param service Service being accessed
     * @param principal Principal requesting authentication
     * @return Provider selected by Groovy script or null
     */
    @Override
    public MultifactorAuthenticationProvider resolve(
        Collection<MultifactorAuthenticationProvider> providers,
        RegisteredService service,
        Principal principal);
}

Groovy Script Example:

// Example Groovy script for custom provider selection
// Script receives: providers, service, principal, logger

import org.apereo.cas.authentication.MultifactorAuthenticationProvider

// Custom selection logic
def userAttributes = principal.getAttributes()
def userRole = userAttributes.get("role")

if (userRole?.contains("admin")) {
    // Admins get highest security provider
    return providers.find { it.getId() == "yubikey" } ?: providers.first()
} else if (service?.getServiceId()?.contains("banking")) {
    // Banking services require specific provider
    return providers.find { it.getId() == "sms" }
} else {
    // Default to lowest friction provider
    return providers.min { it.getOrder() }
}

Authentication Transaction Management

FinalMultifactorAuthenticationTransactionWebflowEventResolver

Final resolver that handles authentication transaction completion and ticket granting.

/**
 * Final resolver handling authentication transaction completion and ticket granting
 */
public class FinalMultifactorAuthenticationTransactionWebflowEventResolver 
    extends BaseMultifactorAuthenticationProviderEventResolver {
    
    /**
     * Constructor
     * @param webflowEventResolutionConfigurationContext Configuration context
     */
    public FinalMultifactorAuthenticationTransactionWebflowEventResolver(
        CasWebflowEventResolutionConfigurationContext webflowEventResolutionConfigurationContext);
    
    /**
     * Resolve events for transaction completion
     * @param context The webflow request context
     * @return Set of resolved events for transaction completion
     */
    @Override
    public Set<Event> resolveInternal(RequestContext context);
    
    /**
     * Resolve single event for transaction completion (audited method)
     * @param context The webflow request context
     * @return Single resolved event for transaction completion
     */
    @Audit(action = AuditableActions.AUTHENTICATION_EVENT_RESOLVED,
           actionResolverName = AuditActionResolvers.AUTHENTICATION_EVENT_RESOLVED_ACTION_RESOLVER,
           resourceResolverName = AuditResourceResolvers.AUTHENTICATION_EVENT_RESOLVED_RESOURCE_RESOLVER)
    public Event resolveSingle(RequestContext context);
}

Configuration Examples:

@Configuration
public class MfaProviderSelectionConfiguration {
    
    @Bean
    @ConditionalOnMissingBean(name = "multifactorAuthenticationProviderSelector")
    public MultifactorAuthenticationProviderSelector multifactorAuthenticationProviderSelector() {
        return new RankedMultifactorAuthenticationProviderSelector();
    }
    
    @Bean
    @ConditionalOnProperty(name = "cas.authn.mfa.provider-selector.groovy.location")
    public MultifactorAuthenticationProviderSelector groovyProviderSelector(
        @Value("${cas.authn.mfa.provider-selector.groovy.location}") Resource groovyScript) {
        return new GroovyScriptMultifactorAuthenticationProviderSelector(groovyScript);
    }
    
    @Bean
    @ConditionalOnProperty(name = "cas.authn.mfa.provider-selector.chaining.enabled", havingValue = "true")
    public MultifactorAuthenticationProviderSelector chainingProviderSelector(
        ConfigurableApplicationContext applicationContext,
        MultifactorAuthenticationFailureModeEvaluator failureModeEvaluator) {
        return new ChainingMultifactorAuthenticationProviderSelector(applicationContext, failureModeEvaluator);
    }
}

Provider Selection Usage Patterns

Custom Provider Selection Logic

@Component
public class CustomProviderSelectionLogic {
    
    @Bean
    public MultifactorAuthenticationProviderSelector customProviderSelector() {
        return new CustomProviderSelector();
    }
    
    private static class CustomProviderSelector implements MultifactorAuthenticationProviderSelector {
        
        @Override
        public MultifactorAuthenticationProvider resolve(
            Collection<MultifactorAuthenticationProvider> providers,
            RegisteredService service,
            Principal principal) {
            
            // Example: Select based on user attributes
            val userAttributes = principal.getAttributes();
            val department = userAttributes.get("department");
            
            if (department != null && department.contains("finance")) {
                // Finance users get hardware tokens
                return providers.stream()
                    .filter(p -> "yubikey".equals(p.getId()))
                    .findFirst()
                    .orElse(null);
            }
            
            // Example: Select based on service properties
            if (service != null) {
                val serviceProperties = service.getProperties();
                val requiredMfa = serviceProperties.get("requiredMfaProvider");
                if (requiredMfa != null) {
                    return providers.stream()
                        .filter(p -> requiredMfa.getValue().equals(p.getId()))
                        .findFirst()
                        .orElse(null);
                }
            }
            
            // Default: Select highest ranked available provider
            return providers.stream()
                .min(Comparator.comparing(MultifactorAuthenticationProvider::getOrder))
                .orElse(null);
        }
    }
}

Transaction Completion Handling

@Configuration
public class MfaTransactionConfiguration {
    
    @Bean
    public CasWebflowEventResolver finalMultifactorAuthenticationTransactionEventResolver(
        @Qualifier("casWebflowConfigurationContext")
        CasWebflowEventResolutionConfigurationContext context) {
        return new FinalMultifactorAuthenticationTransactionWebflowEventResolver(context);
    }
    
    @EventListener
    public void handleMfaTransactionCompletion(MultifactorAuthenticationTransactionCompleteEvent event) {
        val authentication = event.getAuthentication();
        val service = event.getService();
        
        // Custom logic after MFA transaction completion
        logger.info("MFA transaction completed for user {} accessing service {}", 
                   authentication.getPrincipal().getId(), 
                   service != null ? service.getId() : "unknown");
        
        // Additional processing like audit logging, metrics, etc.
    }
}

Integration with Authentication Context

The authentication components integrate with the broader CAS authentication context:

// Example of using components in authentication flow
public class CustomAuthenticationHandler implements AuthenticationHandler {
    
    private final MultifactorAuthenticationProviderSelector providerSelector;
    
    public CustomAuthenticationHandler(MultifactorAuthenticationProviderSelector providerSelector) {
        this.providerSelector = providerSelector;
    }
    
    @Override
    public AuthenticationHandlerExecutionResult authenticate(Credential credential) throws GeneralSecurityException {
        // During authentication, select appropriate MFA provider
        val availableProviders = getAvailableMfaProviders();
        val service = getServiceFromContext();
        val principal = extractPrincipal(credential);
        
        val selectedProvider = providerSelector.resolve(availableProviders, service, principal);
        
        if (selectedProvider != null) {
            // Store selected provider for webflow to use
            storeSelectedProvider(selectedProvider);
        }
        
        return createSuccessfulAuthenticationResult(credential);
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-apereo-cas--cas-server-core-webflow-mfa-api

docs

authentication-components.md

event-resolution.md

index.md

provider-selection.md

webflow-actions.md

webflow-configuration.md

webflow-utilities.md

tile.json