use of org.apereo.cas.authentication.principal.Service in project cas by apereo.
the class GroovyScriptMultifactorAuthenticationPolicyEventResolver method resolveInternal.
@Override
public Set<Event> resolveInternal(final RequestContext context) {
final Service service = resolveServiceFromAuthenticationRequest(context);
final RegisteredService registeredService = resolveRegisteredServiceInRequestContext(context);
final Authentication authentication = WebUtils.getAuthentication(context);
if (groovyScript == null) {
LOGGER.debug("No groovy script is configured for multifactor authentication");
return null;
}
if (!ResourceUtils.doesResourceExist(groovyScript)) {
LOGGER.warn("No groovy script is found at [{}] for multifactor authentication", groovyScript);
return null;
}
if (authentication == null) {
LOGGER.debug("No authentication is available to determine event for principal");
return null;
}
if (registeredService == null || service == null) {
LOGGER.debug("No registered service is available to determine event for principal [{}]", authentication.getPrincipal());
return null;
}
final Map<String, MultifactorAuthenticationProvider> providerMap = MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders(this.applicationContext);
if (providerMap == null || providerMap.isEmpty()) {
LOGGER.error("No multifactor authentication providers are available in the application context");
throw new AuthenticationException();
}
try {
final Object[] args = { service, registeredService, authentication, LOGGER };
final String provider = ScriptingUtils.executeGroovyScript(groovyScript, args, String.class);
LOGGER.debug("Groovy script run for [{}] returned the provider id [{}]", service, provider);
if (StringUtils.isBlank(provider)) {
return null;
}
final Optional<MultifactorAuthenticationProvider> providerFound = resolveProvider(providerMap, provider);
if (providerFound.isPresent()) {
final MultifactorAuthenticationProvider multifactorAuthenticationProvider = providerFound.get();
if (multifactorAuthenticationProvider.isAvailable(registeredService)) {
final Event event = validateEventIdForMatchingTransitionInContext(multifactorAuthenticationProvider.getId(), context, buildEventAttributeMap(authentication.getPrincipal(), registeredService, multifactorAuthenticationProvider));
return CollectionUtils.wrapSet(event);
}
LOGGER.warn("Located multifactor provider [{}], yet the provider cannot be reached or verified", multifactorAuthenticationProvider);
return null;
}
LOGGER.warn("No multifactor provider could be found for [{}]", provider);
throw new AuthenticationException();
} catch (final Exception e) {
LOGGER.error(e.getMessage(), e);
}
return null;
}
use of org.apereo.cas.authentication.principal.Service in project cas by apereo.
the class DefaultCentralAuthenticationService method validateServiceTicket.
@Audit(action = "SERVICE_TICKET_VALIDATE", actionResolverName = "VALIDATE_SERVICE_TICKET_RESOLVER", resourceResolverName = "VALIDATE_SERVICE_TICKET_RESOURCE_RESOLVER")
@Timed(name = "VALIDATE_SERVICE_TICKET_TIMER")
@Metered(name = "VALIDATE_SERVICE_TICKET_METER")
@Counted(name = "VALIDATE_SERVICE_TICKET_COUNTER", monotonic = true)
@Override
public Assertion validateServiceTicket(final String serviceTicketId, final Service service) throws AbstractTicketException {
if (!isTicketAuthenticityVerified(serviceTicketId)) {
LOGGER.info("Service ticket [{}] is not a valid ticket issued by CAS.", serviceTicketId);
throw new InvalidTicketException(serviceTicketId);
}
final ServiceTicket serviceTicket = this.ticketRegistry.getTicket(serviceTicketId, ServiceTicket.class);
if (serviceTicket == null) {
LOGGER.warn("Service ticket [{}] does not exist.", serviceTicketId);
throw new InvalidTicketException(serviceTicketId);
}
try {
/*
* Synchronization on ticket object in case of cache based registry doesn't serialize
* access to critical section. The reason is that cache pulls serialized data and
* builds new object, most likely for each pull. Is this synchronization needed here?
*/
synchronized (serviceTicket) {
if (serviceTicket.isExpired()) {
LOGGER.info("ServiceTicket [{}] has expired.", serviceTicketId);
throw new InvalidTicketException(serviceTicketId);
}
if (!serviceTicket.isValidFor(service)) {
LOGGER.error("Service ticket [{}] with service [{}] does not match supplied service [{}]", serviceTicketId, serviceTicket.getService().getId(), service);
throw new UnrecognizableServiceForServiceTicketValidationException(serviceTicket.getService());
}
}
final Service selectedService = resolveServiceFromAuthenticationRequest(serviceTicket.getService());
LOGGER.debug("Resolved service [{}] from the authentication request", selectedService);
final RegisteredService registeredService = this.servicesManager.findServiceBy(selectedService);
LOGGER.debug("Located registered service definition [{}] from [{}] to handle validation request", registeredService, selectedService);
RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(selectedService, registeredService);
final TicketGrantingTicket root = serviceTicket.getTicketGrantingTicket().getRoot();
final Authentication authentication = getAuthenticationSatisfiedByPolicy(root.getAuthentication(), new ServiceContext(selectedService, registeredService));
final Principal principal = authentication.getPrincipal();
final RegisteredServiceAttributeReleasePolicy attributePolicy = registeredService.getAttributeReleasePolicy();
LOGGER.debug("Attribute policy [{}] is associated with service [{}]", attributePolicy, registeredService);
final Map<String, Object> attributesToRelease = attributePolicy != null ? attributePolicy.getAttributes(principal, selectedService, registeredService) : new HashMap<>();
LOGGER.debug("Calculated attributes for release per the release policy are [{}]", attributesToRelease.keySet());
final String principalId = registeredService.getUsernameAttributeProvider().resolveUsername(principal, selectedService, registeredService);
final Principal modifiedPrincipal = this.principalFactory.createPrincipal(principalId, attributesToRelease);
final AuthenticationBuilder builder = DefaultAuthenticationBuilder.newInstance(authentication);
builder.setPrincipal(modifiedPrincipal);
LOGGER.debug("Principal determined for release to [{}] is [{}]", registeredService.getServiceId(), principalId);
final Authentication finalAuthentication = builder.build();
final AuditableContext audit = AuditableContext.builder().service(selectedService).authentication(finalAuthentication).registeredService(registeredService).retrievePrincipalAttributesFromReleasePolicy(Boolean.FALSE).build();
final AuditableExecutionResult accessResult = this.registeredServiceAccessStrategyEnforcer.execute(audit);
accessResult.throwExceptionIfNeeded();
AuthenticationCredentialsThreadLocalBinder.bindCurrent(finalAuthentication);
final Assertion assertion = new DefaultAssertionBuilder(finalAuthentication).with(selectedService).with(serviceTicket.getTicketGrantingTicket().getChainedAuthentications()).with(serviceTicket.isFromNewLogin()).build();
doPublishEvent(new CasServiceTicketValidatedEvent(this, serviceTicket, assertion));
return assertion;
} finally {
if (serviceTicket.isExpired()) {
deleteTicket(serviceTicketId);
} else {
this.ticketRegistry.updateTicket(serviceTicket);
}
}
}
use of org.apereo.cas.authentication.principal.Service in project cas by apereo.
the class DefaultCentralAuthenticationService method grantServiceTicket.
@Audit(action = "SERVICE_TICKET", actionResolverName = "GRANT_SERVICE_TICKET_RESOLVER", resourceResolverName = "GRANT_SERVICE_TICKET_RESOURCE_RESOLVER")
@Timed(name = "GRANT_SERVICE_TICKET_TIMER")
@Metered(name = "GRANT_SERVICE_TICKET_METER")
@Counted(name = "GRANT_SERVICE_TICKET_COUNTER", monotonic = true)
@Override
public ServiceTicket grantServiceTicket(final String ticketGrantingTicketId, final Service service, final AuthenticationResult authenticationResult) throws AuthenticationException, AbstractTicketException {
final boolean credentialProvided = authenticationResult != null && authenticationResult.isCredentialProvided();
final TicketGrantingTicket ticketGrantingTicket = getTicket(ticketGrantingTicketId, TicketGrantingTicket.class);
final Service selectedService = resolveServiceFromAuthenticationRequest(service);
final RegisteredService registeredService = this.servicesManager.findServiceBy(selectedService);
final AuditableContext audit = AuditableContext.builder().service(selectedService).ticketGrantingTicket(ticketGrantingTicket).registeredService(registeredService).retrievePrincipalAttributesFromReleasePolicy(Boolean.FALSE).build();
final AuditableExecutionResult accessResult = this.registeredServiceAccessStrategyEnforcer.execute(audit);
accessResult.throwExceptionIfNeeded();
final Authentication currentAuthentication = evaluatePossibilityOfMixedPrincipals(authenticationResult, ticketGrantingTicket);
RegisteredServiceAccessStrategyUtils.ensureServiceSsoAccessIsAllowed(registeredService, selectedService, ticketGrantingTicket, credentialProvided);
evaluateProxiedServiceIfNeeded(selectedService, ticketGrantingTicket, registeredService);
// Perform security policy check by getting the authentication that satisfies the configured policy
getAuthenticationSatisfiedByPolicy(currentAuthentication, new ServiceContext(selectedService, registeredService));
final Authentication latestAuthentication = ticketGrantingTicket.getRoot().getAuthentication();
AuthenticationCredentialsThreadLocalBinder.bindCurrent(latestAuthentication);
final Principal principal = latestAuthentication.getPrincipal();
final ServiceTicketFactory factory = (ServiceTicketFactory) this.ticketFactory.get(ServiceTicket.class);
final ServiceTicket serviceTicket = factory.create(ticketGrantingTicket, service, credentialProvided, ServiceTicket.class);
this.ticketRegistry.updateTicket(ticketGrantingTicket);
this.ticketRegistry.addTicket(serviceTicket);
LOGGER.info("Granted ticket [{}] for service [{}] and principal [{}]", serviceTicket.getId(), DigestUtils.abbreviate(service.getId()), principal.getId());
doPublishEvent(new CasServiceTicketGrantedEvent(this, ticketGrantingTicket, serviceTicket));
return serviceTicket;
}
use of org.apereo.cas.authentication.principal.Service in project cas by apereo.
the class CentralAuthenticationServiceImplTests method verifyValidateServiceTicketWithInvalidUsernameAttribute.
@Test
public void verifyValidateServiceTicketWithInvalidUsernameAttribute() {
final Service svc = getService("eduPersonTestInvalid");
final UsernamePasswordCredential cred = CoreAuthenticationTestUtils.getCredentialsWithSameUsernameAndPassword();
final AuthenticationResult ctx = CoreAuthenticationTestUtils.getAuthenticationResult(getAuthenticationSystemSupport(), svc);
final TicketGrantingTicket ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(ctx);
final ServiceTicket serviceTicket = getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket.getId(), svc, ctx);
final Assertion assertion = getCentralAuthenticationService().validateServiceTicket(serviceTicket.getId(), svc);
final Authentication auth = assertion.getPrimaryAuthentication();
/*
* The attribute specified for this service does not resolve.
* Therefore, we expect the default to be returned.
*/
assertEquals(auth.getPrincipal().getId(), cred.getUsername());
}
use of org.apereo.cas.authentication.principal.Service in project cas by apereo.
the class CentralAuthenticationServiceImplTests method verifyGrantServiceTicketWithNoCredsAndSsoFalseAndSsoFalse.
@Test
public void verifyGrantServiceTicketWithNoCredsAndSsoFalseAndSsoFalse() {
final Service svc = getService("TestSsoFalse");
final AuthenticationResult ctx = mock(AuthenticationResult.class);
when(ctx.getAuthentication()).thenReturn(CoreAuthenticationTestUtils.getAuthentication());
when(ctx.isCredentialProvided()).thenReturn(true);
final TicketGrantingTicket ticketGrantingTicket = getCentralAuthenticationService().createTicketGrantingTicket(ctx);
final Service service = getService("eduPersonTest");
getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket.getId(), service, ctx);
this.thrown.expect(UnauthorizedSsoServiceException.class);
when(ctx.isCredentialProvided()).thenReturn(false);
getCentralAuthenticationService().grantServiceTicket(ticketGrantingTicket.getId(), svc, ctx);
}
Aggregations