Search in sources :

Example 6 with AuditableContext

use of org.apereo.cas.audit.AuditableContext in project cas by apereo.

the class ServiceTicketRequestWebflowEventResolver method grantServiceTicket.

/**
 * Grant service ticket for the given credential based on the service and tgt
 * that are found in the request context.
 *
 * @param context the context
 * @return the resulting event. Warning, authentication failure or error.
 * @since 4.1.0
 */
protected Event grantServiceTicket(final RequestContext context) {
    final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context);
    final Credential credential = getCredentialFromContext(context);
    try {
        final Service service = WebUtils.getService(context);
        final Authentication authn = ticketRegistrySupport.getAuthenticationFrom(ticketGrantingTicketId);
        final RegisteredService registeredService = this.servicesManager.findServiceBy(service);
        if (authn != null && registeredService != null) {
            LOGGER.debug("Enforcing access strategy policies for registered service [{}] and principal [{}]", registeredService, authn.getPrincipal());
            final AuditableContext audit = AuditableContext.builder().service(service).authentication(authn).registeredService(registeredService).retrievePrincipalAttributesFromReleasePolicy(Boolean.TRUE).build();
            final AuditableExecutionResult accessResult = this.registeredServiceAccessStrategyEnforcer.execute(audit);
            accessResult.throwExceptionIfNeeded();
        }
        final AuthenticationResult authenticationResult = this.authenticationSystemSupport.handleAndFinalizeSingleAuthenticationTransaction(service, credential);
        final ServiceTicket serviceTicketId = this.centralAuthenticationService.grantServiceTicket(ticketGrantingTicketId, service, authenticationResult);
        WebUtils.putServiceTicketInRequestScope(context, serviceTicketId);
        WebUtils.putWarnCookieIfRequestParameterPresent(this.warnCookieGenerator, context);
        return newEvent(CasWebflowConstants.TRANSITION_ID_WARN);
    } catch (final AuthenticationException | AbstractTicketException e) {
        return newEvent(CasWebflowConstants.TRANSITION_ID_AUTHENTICATION_FAILURE, e);
    }
}
Also used : AuditableContext(org.apereo.cas.audit.AuditableContext) Credential(org.apereo.cas.authentication.Credential) RegisteredService(org.apereo.cas.services.RegisteredService) AuthenticationException(org.apereo.cas.authentication.AuthenticationException) Authentication(org.apereo.cas.authentication.Authentication) CentralAuthenticationService(org.apereo.cas.CentralAuthenticationService) RegisteredService(org.apereo.cas.services.RegisteredService) Service(org.apereo.cas.authentication.principal.Service) ServiceTicket(org.apereo.cas.ticket.ServiceTicket) AbstractTicketException(org.apereo.cas.ticket.AbstractTicketException) AuditableExecutionResult(org.apereo.cas.audit.AuditableExecutionResult) AuthenticationResult(org.apereo.cas.authentication.AuthenticationResult)

Example 7 with AuditableContext

use of org.apereo.cas.audit.AuditableContext in project cas by apereo.

the class DefaultCentralAuthenticationService method grantProxyTicket.

@Audit(action = "PROXY_TICKET", actionResolverName = "GRANT_PROXY_TICKET_RESOLVER", resourceResolverName = "GRANT_PROXY_TICKET_RESOURCE_RESOLVER")
@Timed(name = "GRANT_PROXY_TICKET_TIMER")
@Metered(name = "GRANT_PROXY_TICKET_METER")
@Counted(name = "GRANT_PROXY_TICKET_COUNTER", monotonic = true)
@Override
public ProxyTicket grantProxyTicket(final String proxyGrantingTicket, final Service service) throws AbstractTicketException {
    final ProxyGrantingTicket proxyGrantingTicketObject = getTicket(proxyGrantingTicket, ProxyGrantingTicket.class);
    final RegisteredService registeredService = this.servicesManager.findServiceBy(service);
    try {
        final AuditableContext audit = AuditableContext.builder().service(service).ticketGrantingTicket(proxyGrantingTicketObject).registeredService(registeredService).retrievePrincipalAttributesFromReleasePolicy(Boolean.FALSE).build();
        final AuditableExecutionResult accessResult = this.registeredServiceAccessStrategyEnforcer.execute(audit);
        accessResult.throwExceptionIfNeeded();
        RegisteredServiceAccessStrategyUtils.ensureServiceSsoAccessIsAllowed(registeredService, service, proxyGrantingTicketObject);
    } catch (final PrincipalException e) {
        throw new UnauthorizedSsoServiceException();
    }
    evaluateProxiedServiceIfNeeded(service, proxyGrantingTicketObject, registeredService);
    // Perform security policy check by getting the authentication that satisfies the configured policy
    // This throws if no suitable policy is found
    getAuthenticationSatisfiedByPolicy(proxyGrantingTicketObject.getRoot().getAuthentication(), new ServiceContext(service, registeredService));
    final Authentication authentication = proxyGrantingTicketObject.getRoot().getAuthentication();
    AuthenticationCredentialsThreadLocalBinder.bindCurrent(authentication);
    final Principal principal = authentication.getPrincipal();
    final ProxyTicketFactory factory = (ProxyTicketFactory) this.ticketFactory.get(ProxyTicket.class);
    final ProxyTicket proxyTicket = factory.create(proxyGrantingTicketObject, service, ProxyTicket.class);
    this.ticketRegistry.updateTicket(proxyGrantingTicketObject);
    this.ticketRegistry.addTicket(proxyTicket);
    LOGGER.info("Granted ticket [{}] for service [{}] for user [{}]", proxyTicket.getId(), service.getId(), principal.getId());
    doPublishEvent(new CasProxyTicketGrantedEvent(this, proxyGrantingTicketObject, proxyTicket));
    return proxyTicket;
}
Also used : AuditableContext(org.apereo.cas.audit.AuditableContext) RegisteredService(org.apereo.cas.services.RegisteredService) ProxyTicketFactory(org.apereo.cas.ticket.proxy.ProxyTicketFactory) UnauthorizedSsoServiceException(org.apereo.cas.services.UnauthorizedSsoServiceException) PrincipalException(org.apereo.cas.authentication.PrincipalException) MixedPrincipalException(org.apereo.cas.authentication.exceptions.MixedPrincipalException) ServiceContext(org.apereo.cas.services.ServiceContext) Authentication(org.apereo.cas.authentication.Authentication) ProxyGrantingTicket(org.apereo.cas.ticket.proxy.ProxyGrantingTicket) AuditableExecutionResult(org.apereo.cas.audit.AuditableExecutionResult) Principal(org.apereo.cas.authentication.principal.Principal) ProxyTicket(org.apereo.cas.ticket.proxy.ProxyTicket) CasProxyTicketGrantedEvent(org.apereo.cas.support.events.ticket.CasProxyTicketGrantedEvent) Audit(org.apereo.inspektr.audit.annotation.Audit) Counted(com.codahale.metrics.annotation.Counted) Metered(com.codahale.metrics.annotation.Metered) Timed(com.codahale.metrics.annotation.Timed)

Example 8 with AuditableContext

use of org.apereo.cas.audit.AuditableContext 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);
        }
    }
}
Also used : AuditableContext(org.apereo.cas.audit.AuditableContext) RegisteredService(org.apereo.cas.services.RegisteredService) DefaultAuthenticationBuilder(org.apereo.cas.authentication.DefaultAuthenticationBuilder) AuthenticationBuilder(org.apereo.cas.authentication.AuthenticationBuilder) TicketGrantingTicket(org.apereo.cas.ticket.TicketGrantingTicket) ServiceContext(org.apereo.cas.services.ServiceContext) UnrecognizableServiceForServiceTicketValidationException(org.apereo.cas.ticket.UnrecognizableServiceForServiceTicketValidationException) Assertion(org.apereo.cas.validation.Assertion) RegisteredService(org.apereo.cas.services.RegisteredService) Service(org.apereo.cas.authentication.principal.Service) ServiceTicket(org.apereo.cas.ticket.ServiceTicket) DefaultAssertionBuilder(org.apereo.cas.validation.DefaultAssertionBuilder) Authentication(org.apereo.cas.authentication.Authentication) CasServiceTicketValidatedEvent(org.apereo.cas.support.events.ticket.CasServiceTicketValidatedEvent) InvalidTicketException(org.apereo.cas.ticket.InvalidTicketException) AuditableExecutionResult(org.apereo.cas.audit.AuditableExecutionResult) Principal(org.apereo.cas.authentication.principal.Principal) RegisteredServiceAttributeReleasePolicy(org.apereo.cas.services.RegisteredServiceAttributeReleasePolicy) Audit(org.apereo.inspektr.audit.annotation.Audit) Counted(com.codahale.metrics.annotation.Counted) Metered(com.codahale.metrics.annotation.Metered) Timed(com.codahale.metrics.annotation.Timed)

Example 9 with AuditableContext

use of org.apereo.cas.audit.AuditableContext 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;
}
Also used : AuditableContext(org.apereo.cas.audit.AuditableContext) RegisteredService(org.apereo.cas.services.RegisteredService) ServiceTicketFactory(org.apereo.cas.ticket.ServiceTicketFactory) CasServiceTicketGrantedEvent(org.apereo.cas.support.events.ticket.CasServiceTicketGrantedEvent) TicketGrantingTicket(org.apereo.cas.ticket.TicketGrantingTicket) Authentication(org.apereo.cas.authentication.Authentication) ServiceContext(org.apereo.cas.services.ServiceContext) RegisteredService(org.apereo.cas.services.RegisteredService) Service(org.apereo.cas.authentication.principal.Service) ServiceTicket(org.apereo.cas.ticket.ServiceTicket) AuditableExecutionResult(org.apereo.cas.audit.AuditableExecutionResult) Principal(org.apereo.cas.authentication.principal.Principal) Audit(org.apereo.inspektr.audit.annotation.Audit) Counted(com.codahale.metrics.annotation.Counted) Metered(com.codahale.metrics.annotation.Metered) Timed(com.codahale.metrics.annotation.Timed)

Example 10 with AuditableContext

use of org.apereo.cas.audit.AuditableContext in project cas by apereo.

the class DefaultCentralAuthenticationService method createTicketGrantingTicket.

@Audit(action = "TICKET_GRANTING_TICKET", actionResolverName = "CREATE_TICKET_GRANTING_TICKET_RESOLVER", resourceResolverName = "CREATE_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER")
@Timed(name = "CREATE_TICKET_GRANTING_TICKET_TIMER")
@Metered(name = "CREATE_TICKET_GRANTING_TICKET_METER")
@Counted(name = "CREATE_TICKET_GRANTING_TICKET_COUNTER", monotonic = true)
@Override
public TicketGrantingTicket createTicketGrantingTicket(final AuthenticationResult authenticationResult) throws AuthenticationException, AbstractTicketException {
    final Authentication authentication = authenticationResult.getAuthentication();
    final Service service = authenticationResult.getService();
    AuthenticationCredentialsThreadLocalBinder.bindCurrent(authentication);
    if (service != null) {
        final Service selectedService = resolveServiceFromAuthenticationRequest(service);
        LOGGER.debug("Resolved service [{}] from the authentication request", selectedService);
        final RegisteredService registeredService = this.servicesManager.findServiceBy(selectedService);
        final AuditableContext audit = AuditableContext.builder().service(service).authentication(authentication).registeredService(registeredService).retrievePrincipalAttributesFromReleasePolicy(Boolean.FALSE).build();
        final AuditableExecutionResult accessResult = this.registeredServiceAccessStrategyEnforcer.execute(audit);
        accessResult.throwExceptionIfNeeded();
    }
    final TicketGrantingTicketFactory factory = (TicketGrantingTicketFactory) this.ticketFactory.get(TicketGrantingTicket.class);
    final TicketGrantingTicket ticketGrantingTicket = factory.create(authentication, TicketGrantingTicket.class);
    this.ticketRegistry.addTicket(ticketGrantingTicket);
    doPublishEvent(new CasTicketGrantingTicketCreatedEvent(this, ticketGrantingTicket));
    return ticketGrantingTicket;
}
Also used : AuditableContext(org.apereo.cas.audit.AuditableContext) RegisteredService(org.apereo.cas.services.RegisteredService) CasTicketGrantingTicketCreatedEvent(org.apereo.cas.support.events.ticket.CasTicketGrantingTicketCreatedEvent) Authentication(org.apereo.cas.authentication.Authentication) TicketGrantingTicket(org.apereo.cas.ticket.TicketGrantingTicket) RegisteredService(org.apereo.cas.services.RegisteredService) Service(org.apereo.cas.authentication.principal.Service) AuditableExecutionResult(org.apereo.cas.audit.AuditableExecutionResult) TicketGrantingTicketFactory(org.apereo.cas.ticket.TicketGrantingTicketFactory) Audit(org.apereo.inspektr.audit.annotation.Audit) Counted(com.codahale.metrics.annotation.Counted) Metered(com.codahale.metrics.annotation.Metered) Timed(com.codahale.metrics.annotation.Timed)

Aggregations

AuditableContext (org.apereo.cas.audit.AuditableContext)13 AuditableExecutionResult (org.apereo.cas.audit.AuditableExecutionResult)13 RegisteredService (org.apereo.cas.services.RegisteredService)11 Authentication (org.apereo.cas.authentication.Authentication)10 Service (org.apereo.cas.authentication.principal.Service)7 Counted (com.codahale.metrics.annotation.Counted)5 Metered (com.codahale.metrics.annotation.Metered)5 Timed (com.codahale.metrics.annotation.Timed)5 Audit (org.apereo.inspektr.audit.annotation.Audit)5 Principal (org.apereo.cas.authentication.principal.Principal)4 ServiceTicket (org.apereo.cas.ticket.ServiceTicket)4 TicketGrantingTicket (org.apereo.cas.ticket.TicketGrantingTicket)4 ServiceContext (org.apereo.cas.services.ServiceContext)3 CentralAuthenticationService (org.apereo.cas.CentralAuthenticationService)2 AuthenticationResult (org.apereo.cas.authentication.AuthenticationResult)2 PrincipalException (org.apereo.cas.authentication.PrincipalException)2 UnauthorizedServiceException (org.apereo.cas.services.UnauthorizedServiceException)2 OAuthRegisteredService (org.apereo.cas.support.oauth.services.OAuthRegisteredService)2 InvalidTicketException (org.apereo.cas.ticket.InvalidTicketException)2 ProxyGrantingTicket (org.apereo.cas.ticket.proxy.ProxyGrantingTicket)2