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));
}
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));
}
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();
}
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();
}
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();
}
Aggregations