Search in sources :

Example 6 with MultifactorAuthenticationProvider

use of org.apereo.cas.authentication.MultifactorAuthenticationProvider in project cas by apereo.

the class SelectiveMultifactorAuthenticationProviderWebflowEventResolver method filterEventsByMultifactorAuthenticationProvider.

/**
 * Filter events by multifactor authentication providers.
 *
 * @param resolveEvents     the resolve events
 * @param authentication    the authentication
 * @param registeredService the registered service
 * @param request           the request
 * @return the set of events
 */
protected Optional<Pair<Collection<Event>, Collection<MultifactorAuthenticationProvider>>> filterEventsByMultifactorAuthenticationProvider(final Collection<Event> resolveEvents, final Authentication authentication, final RegisteredService registeredService, final HttpServletRequest request) {
    LOGGER.debug("Locating multifactor providers to determine support for this authentication sequence");
    val providers = MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders(getConfigurationContext().getApplicationContext());
    if (providers.isEmpty()) {
        LOGGER.debug("No providers are available to honor this request. Moving on...");
        return Optional.of(Pair.of(resolveEvents, new HashSet<>(0)));
    }
    val providerValues = providers.values();
    providerValues.removeIf(p -> resolveEvents.stream().noneMatch(e -> p.matches(e.getId())));
    resolveEvents.removeIf(e -> providerValues.stream().noneMatch(p -> p.matches(e.getId())));
    LOGGER.debug("Finalized set of resolved events are [{}]", resolveEvents);
    val finalEvents = new TreeSet<>(Comparator.comparing(Event::getId));
    finalEvents.addAll(resolveEvents);
    return Optional.of(Pair.of(finalEvents, providerValues));
}
Also used : lombok.val(lombok.val) Collection(java.util.Collection) lombok.val(lombok.val) Set(java.util.Set) MultifactorAuthenticationProvider(org.apereo.cas.authentication.MultifactorAuthenticationProvider) RequestContext(org.springframework.webflow.execution.RequestContext) RegisteredService(org.apereo.cas.services.RegisteredService) BaseMultifactorAuthenticationProviderEventResolver(org.apereo.cas.web.flow.authentication.BaseMultifactorAuthenticationProviderEventResolver) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Slf4j(lombok.extern.slf4j.Slf4j) HttpServletRequest(javax.servlet.http.HttpServletRequest) Pair(org.apache.commons.lang3.tuple.Pair) Authentication(org.apereo.cas.authentication.Authentication) Optional(java.util.Optional) MultifactorAuthenticationUtils(org.apereo.cas.authentication.MultifactorAuthenticationUtils) WebUtils(org.apereo.cas.web.support.WebUtils) Comparator(java.util.Comparator) Event(org.springframework.webflow.execution.Event) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet)

Example 7 with MultifactorAuthenticationProvider

use of org.apereo.cas.authentication.MultifactorAuthenticationProvider in project cas by apereo.

the class DetermineMultifactorPasswordlessAuthenticationAction method doExecute.

@Override
protected Event doExecute(final RequestContext requestContext) {
    val user = WebUtils.getPasswordlessAuthenticationAccount(requestContext, PasswordlessUserAccount.class);
    if (user == null) {
        LOGGER.error("Unable to locate passwordless account in the flow");
        return error();
    }
    if (multifactorTriggerSelectionStrategy.getMultifactorAuthenticationTriggers().isEmpty()) {
        LOGGER.debug("No multifactor authentication triggers are available or defined");
        return success();
    }
    if (!shouldActivateMultifactorAuthenticationFor(requestContext, user)) {
        LOGGER.debug("User [{}] is not activated to use CAS-provided multifactor authentication providers. " + "You may wish to re-examine your CAS configuration to enable and allow for multifactor authentication to be " + "combined with passwordless authentication", user);
        return success();
    }
    val attributes = CoreAuthenticationUtils.convertAttributeValuesToMultiValuedObjects((Map) user.getAttributes());
    val principal = this.passwordlessPrincipalFactory.createPrincipal(user.getId(), attributes);
    val auth = DefaultAuthenticationBuilder.newInstance().setPrincipal(principal).build();
    val service = WebUtils.getService(requestContext);
    val result = resolveMultifactorAuthenticationProvider(requestContext, auth, service);
    if (result.isEmpty()) {
        LOGGER.debug("No CAS-provided multifactor authentication trigger required user [{}] to proceed with MFA. " + "CAS will proceed with its normal passwordless authentication flow.", user);
        return success();
    }
    populateContextWithAuthenticationResult(requestContext, auth, service);
    LOGGER.debug("Proceed with multifactor authentication flow [{}] for user [{}]", result.get(), user);
    return new EventFactorySupport().event(this, result.map(MultifactorAuthenticationProvider::getId).orElse(StringUtils.EMPTY));
}
Also used : lombok.val(lombok.val) MultifactorAuthenticationProvider(org.apereo.cas.authentication.MultifactorAuthenticationProvider) EventFactorySupport(org.springframework.webflow.action.EventFactorySupport)

Example 8 with MultifactorAuthenticationProvider

use of org.apereo.cas.authentication.MultifactorAuthenticationProvider in project cas by apereo.

the class TicketGrantingTicketResourceTests method initialize.

@BeforeEach
public void initialize() {
    val httpRequestCredentialFactory = new UsernamePasswordRestHttpRequestCredentialFactory() {

        @Override
        public List<Credential> fromAuthentication(final HttpServletRequest request, final MultiValueMap<String, String> requestBody, final Authentication authentication, final MultifactorAuthenticationProvider provider) {
            if (provider.getId().contains("unknown")) {
                return List.of();
            }
            return List.of(new UsernamePasswordCredential("mfa-user", "mfa-user"));
        }
    };
    val publisher = mock(ApplicationEventPublisher.class);
    val manager = mock(AuthenticationManager.class);
    lenient().when(manager.authenticate(any(AuthenticationTransaction.class))).thenReturn(CoreAuthenticationTestUtils.getAuthentication());
    lenient().when(ticketSupport.getAuthenticationFrom(anyString())).thenReturn(CoreAuthenticationTestUtils.getAuthentication());
    lenient().when(requestedContextValidator.validateAuthenticationContext(any(), any(), any(), any(), any())).thenReturn(AuthenticationContextValidationResult.builder().success(true).build());
    lenient().when(multifactorTriggerSelectionStrategy.resolve(any(), any(), any(), any(), any())).thenReturn(Optional.empty());
    val authenticationSystemSupport = new DefaultAuthenticationSystemSupport(new DefaultAuthenticationTransactionManager(publisher, manager), new DefaultPrincipalElectionStrategy(), new DefaultAuthenticationResultBuilderFactory(), new DefaultAuthenticationTransactionFactory());
    val api = new DefaultRestAuthenticationService(authenticationSystemSupport, httpRequestCredentialFactory, new WebApplicationServiceFactory(), multifactorTriggerSelectionStrategy, servicesManager, requestedContextValidator);
    val logoutManager = new DefaultLogoutManager(false, new DefaultLogoutExecutionPlan());
    val applicationContext = new StaticApplicationContext();
    applicationContext.refresh();
    this.ticketGrantingTicketResourceUnderTest = new TicketGrantingTicketResource(api, casMock, new DefaultTicketGrantingTicketResourceEntityResponseFactory(), new GenericWebApplicationContext(), new DefaultSingleLogoutRequestExecutor(casMock, logoutManager, applicationContext));
    this.mockMvc = MockMvcBuilders.standaloneSetup(this.ticketGrantingTicketResourceUnderTest).defaultRequest(get("/").contextPath("/cas").contentType(MediaType.APPLICATION_FORM_URLENCODED)).build();
}
Also used : lombok.val(lombok.val) UsernamePasswordCredential(org.apereo.cas.authentication.credential.UsernamePasswordCredential) Credential(org.apereo.cas.authentication.Credential) DefaultLogoutExecutionPlan(org.apereo.cas.logout.DefaultLogoutExecutionPlan) TicketGrantingTicketResource(org.apereo.cas.support.rest.resources.TicketGrantingTicketResource) DefaultLogoutManager(org.apereo.cas.logout.DefaultLogoutManager) StaticApplicationContext(org.springframework.context.support.StaticApplicationContext) UsernamePasswordRestHttpRequestCredentialFactory(org.apereo.cas.rest.factory.UsernamePasswordRestHttpRequestCredentialFactory) MultifactorAuthenticationProvider(org.apereo.cas.authentication.MultifactorAuthenticationProvider) TestMultifactorAuthenticationProvider(org.apereo.cas.authentication.mfa.TestMultifactorAuthenticationProvider) DefaultAuthenticationTransactionFactory(org.apereo.cas.authentication.DefaultAuthenticationTransactionFactory) DefaultAuthenticationTransactionManager(org.apereo.cas.authentication.DefaultAuthenticationTransactionManager) DefaultRestAuthenticationService(org.apereo.cas.rest.authentication.DefaultRestAuthenticationService) HttpServletRequest(javax.servlet.http.HttpServletRequest) DefaultPrincipalElectionStrategy(org.apereo.cas.authentication.principal.DefaultPrincipalElectionStrategy) DefaultAuthenticationResultBuilderFactory(org.apereo.cas.authentication.DefaultAuthenticationResultBuilderFactory) Authentication(org.apereo.cas.authentication.Authentication) WebApplicationServiceFactory(org.apereo.cas.authentication.principal.WebApplicationServiceFactory) DefaultTicketGrantingTicketResourceEntityResponseFactory(org.apereo.cas.rest.factory.DefaultTicketGrantingTicketResourceEntityResponseFactory) DefaultAuthenticationSystemSupport(org.apereo.cas.authentication.DefaultAuthenticationSystemSupport) DefaultSingleLogoutRequestExecutor(org.apereo.cas.logout.slo.DefaultSingleLogoutRequestExecutor) AuthenticationTransaction(org.apereo.cas.authentication.AuthenticationTransaction) UsernamePasswordCredential(org.apereo.cas.authentication.credential.UsernamePasswordCredential) GenericWebApplicationContext(org.springframework.web.context.support.GenericWebApplicationContext) MultiValueMap(org.springframework.util.MultiValueMap) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 9 with MultifactorAuthenticationProvider

use of org.apereo.cas.authentication.MultifactorAuthenticationProvider in project cas by apereo.

the class UserAuthenticationResourceTests method initialize.

@BeforeEach
public void initialize() {
    val httpRequestCredentialFactory = new UsernamePasswordRestHttpRequestCredentialFactory() {

        @Override
        public List<Credential> fromAuthentication(final HttpServletRequest request, final MultiValueMap<String, String> requestBody, final Authentication authentication, final MultifactorAuthenticationProvider provider) {
            if (provider.getId().contains("unknown")) {
                return List.of();
            }
            return List.of(new UsernamePasswordCredential("mfa-user", "mfa-user"));
        }
    };
    val api = new DefaultRestAuthenticationService(authenticationSupport, httpRequestCredentialFactory, new WebApplicationServiceFactory(), multifactorTriggerSelectionStrategy, servicesManager, requestedContextValidator);
    this.userAuthenticationResource = new UserAuthenticationResource(api, new DefaultUserAuthenticationResourceEntityResponseFactory(), new GenericApplicationContext());
    this.mockMvc = MockMvcBuilders.standaloneSetup(this.userAuthenticationResource).defaultRequest(get("/").contextPath("/cas").contentType(MediaType.APPLICATION_FORM_URLENCODED)).build();
}
Also used : lombok.val(lombok.val) UsernamePasswordCredential(org.apereo.cas.authentication.credential.UsernamePasswordCredential) Credential(org.apereo.cas.authentication.Credential) UserAuthenticationResource(org.apereo.cas.support.rest.resources.UserAuthenticationResource) UsernamePasswordRestHttpRequestCredentialFactory(org.apereo.cas.rest.factory.UsernamePasswordRestHttpRequestCredentialFactory) MultifactorAuthenticationProvider(org.apereo.cas.authentication.MultifactorAuthenticationProvider) TestMultifactorAuthenticationProvider(org.apereo.cas.authentication.mfa.TestMultifactorAuthenticationProvider) DefaultRestAuthenticationService(org.apereo.cas.rest.authentication.DefaultRestAuthenticationService) HttpServletRequest(javax.servlet.http.HttpServletRequest) DefaultUserAuthenticationResourceEntityResponseFactory(org.apereo.cas.rest.factory.DefaultUserAuthenticationResourceEntityResponseFactory) GenericApplicationContext(org.springframework.context.support.GenericApplicationContext) Authentication(org.apereo.cas.authentication.Authentication) WebApplicationServiceFactory(org.apereo.cas.authentication.principal.WebApplicationServiceFactory) UsernamePasswordCredential(org.apereo.cas.authentication.credential.UsernamePasswordCredential) MultiValueMap(org.springframework.util.MultiValueMap) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 10 with MultifactorAuthenticationProvider

use of org.apereo.cas.authentication.MultifactorAuthenticationProvider in project cas by apereo.

the class ScriptedRegisteredServiceMultifactorAuthenticationTrigger method isActivated.

@Override
public Optional<MultifactorAuthenticationProvider> isActivated(final Authentication authentication, final RegisteredService registeredService, final HttpServletRequest httpServletRequest, final HttpServletResponse response, final Service service) {
    if (authentication == null || registeredService == null) {
        LOGGER.debug("No authentication or service is available to determine event for principal");
        return Optional.empty();
    }
    val policy = registeredService.getMultifactorPolicy();
    if (policy == null || StringUtils.isBlank(policy.getScript())) {
        LOGGER.trace("Multifactor authentication policy is absent or does not define a script to trigger multifactor authentication");
        return Optional.empty();
    }
    val mfaScript = policy.getScript();
    val providerMap = MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders(this.applicationContext);
    if (providerMap.isEmpty()) {
        LOGGER.error("No multifactor authentication providers are available in the application context");
        throw new AuthenticationException(new MultifactorAuthenticationProviderAbsentException());
    }
    LOGGER.trace("Locating multifactor authentication trigger script [{}] in script cache...", mfaScript);
    if (!scriptCache.containsKey(mfaScript)) {
        val matcherInline = ScriptingUtils.getMatcherForInlineGroovyScript(mfaScript);
        val matcherFile = ScriptingUtils.getMatcherForExternalGroovyScript(mfaScript);
        if (matcherInline.find()) {
            val script = new GroovyShellScript(matcherInline.group(1));
            scriptCache.put(mfaScript, script);
            LOGGER.trace("Caching multifactor authentication trigger script as an executable shell script");
        } else if (matcherFile.find()) {
            try {
                val scriptPath = SpringExpressionLanguageValueResolver.getInstance().resolve(matcherFile.group());
                val resource = ResourceUtils.getResourceFrom(scriptPath);
                val script = new WatchableGroovyScriptResource(resource);
                scriptCache.put(mfaScript, script);
                LOGGER.trace("Caching multifactor authentication trigger script as script resource [{}]", resource);
            } catch (final Exception e) {
                LoggingUtils.error(LOGGER, e);
            }
        }
    }
    if (scriptCache.containsKey(mfaScript)) {
        val executableScript = scriptCache.get(mfaScript);
        LOGGER.debug("Executing multifactor authentication trigger script [{}]", executableScript);
        val result = executableScript.execute(new Object[] { authentication, registeredService, httpServletRequest, service, applicationContext, LOGGER }, String.class);
        LOGGER.debug("Multifactor authentication provider delivered by trigger script is [{}]", result);
        if (StringUtils.isBlank(result)) {
            LOGGER.debug("No multifactor authentication is returned from trigger script");
            return Optional.empty();
        }
        val providerResult = providerMap.values().stream().filter(provider -> provider.getId().equalsIgnoreCase(result)).findFirst();
        if (providerResult.isEmpty()) {
            LOGGER.error("Unable to locate multifactor authentication provider [{}] in the application context", result);
            throw new AuthenticationException(new MultifactorAuthenticationProviderAbsentException());
        }
        return providerResult;
    }
    return Optional.empty();
}
Also used : lombok.val(lombok.val) CasConfigurationProperties(org.apereo.cas.configuration.CasConfigurationProperties) Ordered(org.springframework.core.Ordered) Setter(lombok.Setter) Getter(lombok.Getter) RequiredArgsConstructor(lombok.RequiredArgsConstructor) MultifactorAuthenticationProvider(org.apereo.cas.authentication.MultifactorAuthenticationProvider) MultifactorAuthenticationTrigger(org.apereo.cas.authentication.MultifactorAuthenticationTrigger) StringUtils(org.apache.commons.lang3.StringUtils) MultifactorAuthenticationProviderAbsentException(org.apereo.cas.authentication.MultifactorAuthenticationProviderAbsentException) LoggingUtils(org.apereo.cas.util.LoggingUtils) ScriptingUtils(org.apereo.cas.util.scripting.ScriptingUtils) HttpServletRequest(javax.servlet.http.HttpServletRequest) Authentication(org.apereo.cas.authentication.Authentication) Map(java.util.Map) JsonIgnore(com.fasterxml.jackson.annotation.JsonIgnore) MultifactorAuthenticationUtils(org.apereo.cas.authentication.MultifactorAuthenticationUtils) GroovyShellScript(org.apereo.cas.util.scripting.GroovyShellScript) AuthenticationException(org.apereo.cas.authentication.AuthenticationException) ResourceUtils(org.apereo.cas.util.ResourceUtils) lombok.val(lombok.val) HttpServletResponse(javax.servlet.http.HttpServletResponse) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) WatchableGroovyScriptResource(org.apereo.cas.util.scripting.WatchableGroovyScriptResource) ApplicationContext(org.springframework.context.ApplicationContext) RegisteredService(org.apereo.cas.services.RegisteredService) Slf4j(lombok.extern.slf4j.Slf4j) SpringExpressionLanguageValueResolver(org.apereo.cas.util.spring.SpringExpressionLanguageValueResolver) Transient(javax.persistence.Transient) Service(org.apereo.cas.authentication.principal.Service) Optional(java.util.Optional) ExecutableCompiledGroovyScript(org.apereo.cas.util.scripting.ExecutableCompiledGroovyScript) AuthenticationException(org.apereo.cas.authentication.AuthenticationException) MultifactorAuthenticationProviderAbsentException(org.apereo.cas.authentication.MultifactorAuthenticationProviderAbsentException) WatchableGroovyScriptResource(org.apereo.cas.util.scripting.WatchableGroovyScriptResource) GroovyShellScript(org.apereo.cas.util.scripting.GroovyShellScript) MultifactorAuthenticationProviderAbsentException(org.apereo.cas.authentication.MultifactorAuthenticationProviderAbsentException) AuthenticationException(org.apereo.cas.authentication.AuthenticationException)

Aggregations

lombok.val (lombok.val)13 MultifactorAuthenticationProvider (org.apereo.cas.authentication.MultifactorAuthenticationProvider)13 Authentication (org.apereo.cas.authentication.Authentication)11 HttpServletRequest (javax.servlet.http.HttpServletRequest)10 Optional (java.util.Optional)9 RegisteredService (org.apereo.cas.services.RegisteredService)8 Slf4j (lombok.extern.slf4j.Slf4j)7 MultifactorAuthenticationUtils (org.apereo.cas.authentication.MultifactorAuthenticationUtils)7 HttpServletResponse (javax.servlet.http.HttpServletResponse)6 RequiredArgsConstructor (lombok.RequiredArgsConstructor)6 AuthenticationException (org.apereo.cas.authentication.AuthenticationException)6 MultifactorAuthenticationTrigger (org.apereo.cas.authentication.MultifactorAuthenticationTrigger)6 Service (org.apereo.cas.authentication.principal.Service)6 CasConfigurationProperties (org.apereo.cas.configuration.CasConfigurationProperties)6 ApplicationContext (org.springframework.context.ApplicationContext)6 Getter (lombok.Getter)5 Setter (lombok.Setter)5 Ordered (org.springframework.core.Ordered)5 Collectors (java.util.stream.Collectors)4 MultifactorAuthenticationProviderAbsentException (org.apereo.cas.authentication.MultifactorAuthenticationProviderAbsentException)4