Search in sources :

Example 6 with Audit

use of org.apereo.inspektr.audit.annotation.Audit in project cas by apereo.

the class DefaultCentralAuthenticationService method grantProxyTicket.

@Audit(action = AuditableActions.PROXY_TICKET, actionResolverName = AuditActionResolvers.GRANT_PROXY_TICKET_RESOLVER, resourceResolverName = AuditResourceResolvers.GRANT_PROXY_TICKET_RESOURCE_RESOLVER)
@Override
public ProxyTicket grantProxyTicket(final String proxyGrantingTicket, final Service service) throws AbstractTicketException {
    val proxyGrantingTicketObject = getTicket(proxyGrantingTicket, ProxyGrantingTicket.class);
    val registeredService = configurationContext.getServicesManager().findServiceBy(service);
    try {
        enforceRegisteredServiceAccess(service, proxyGrantingTicketObject, registeredService);
        RegisteredServiceAccessStrategyUtils.ensureServiceSsoAccessIsAllowed(registeredService, service, proxyGrantingTicketObject);
    } catch (final Exception e) {
        LoggingUtils.warn(LOGGER, e);
        throw new UnauthorizedSsoServiceException();
    }
    evaluateProxiedServiceIfNeeded(service, proxyGrantingTicketObject, registeredService);
    getAuthenticationSatisfiedByPolicy(proxyGrantingTicketObject.getRoot().getAuthentication(), new ServiceContext(service, registeredService));
    val authentication = proxyGrantingTicketObject.getRoot().getAuthentication();
    AuthenticationCredentialsThreadLocalBinder.bindCurrent(authentication);
    return configurationContext.getLockRepository().execute(proxyGrantingTicketObject.getId(), Unchecked.supplier(new CheckedSupplier<ProxyTicket>() {

        @Override
        public ProxyTicket get() throws Throwable {
            val principal = authentication.getPrincipal();
            val factory = (ProxyTicketFactory) configurationContext.getTicketFactory().get(ProxyTicket.class);
            val proxyTicket = factory.create(proxyGrantingTicketObject, service, ProxyTicket.class);
            configurationContext.getTicketRegistry().updateTicket(proxyGrantingTicketObject);
            configurationContext.getTicketRegistry().addTicket(proxyTicket);
            LOGGER.info("Granted proxy ticket [{}] for service [{}] for user [{}]", proxyTicket.getId(), service.getId(), principal.getId());
            doPublishEvent(new CasProxyTicketGrantedEvent(this, proxyGrantingTicketObject, proxyTicket));
            return proxyTicket;
        }
    })).orElseThrow(UnauthorizedProxyingException::new);
}
Also used : lombok.val(lombok.val) UnauthorizedSsoServiceException(org.apereo.cas.services.UnauthorizedSsoServiceException) ServiceContext(org.apereo.cas.services.ServiceContext) UnauthorizedSsoServiceException(org.apereo.cas.services.UnauthorizedSsoServiceException) AuthenticationException(org.apereo.cas.authentication.AuthenticationException) UnauthorizedProxyingException(org.apereo.cas.services.UnauthorizedProxyingException) MixedPrincipalException(org.apereo.cas.authentication.exceptions.MixedPrincipalException) UnrecognizableServiceForServiceTicketValidationException(org.apereo.cas.ticket.UnrecognizableServiceForServiceTicketValidationException) InvalidTicketException(org.apereo.cas.ticket.InvalidTicketException) AbstractTicketException(org.apereo.cas.ticket.AbstractTicketException) ProxyTicket(org.apereo.cas.ticket.proxy.ProxyTicket) UnauthorizedProxyingException(org.apereo.cas.services.UnauthorizedProxyingException) CasProxyTicketGrantedEvent(org.apereo.cas.support.events.ticket.CasProxyTicketGrantedEvent) Audit(org.apereo.inspektr.audit.annotation.Audit)

Example 7 with Audit

use of org.apereo.inspektr.audit.annotation.Audit in project cas by apereo.

the class DefaultCentralAuthenticationService method validateServiceTicket.

@Audit(action = AuditableActions.SERVICE_TICKET_VALIDATE, actionResolverName = AuditActionResolvers.VALIDATE_SERVICE_TICKET_RESOLVER, resourceResolverName = AuditResourceResolvers.VALIDATE_SERVICE_TICKET_RESOURCE_RESOLVER)
@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);
    }
    val serviceTicket = configurationContext.getTicketRegistry().getTicket(serviceTicketId, ServiceTicket.class);
    if (serviceTicket == null) {
        LOGGER.warn("Service ticket [{}] does not exist.", serviceTicketId);
        throw new InvalidTicketException(serviceTicketId);
    }
    try {
        val selectedService = resolveServiceFromAuthenticationRequest(serviceTicket.getService());
        val resolvedService = resolveServiceFromAuthenticationRequest(service);
        LOGGER.debug("Resolved service [{}] from the authentication request with service [{}] linked to service ticket [{}]", resolvedService, selectedService, serviceTicket.getId());
        configurationContext.getLockRepository().execute(serviceTicket.getId(), Unchecked.supplier(() -> {
            if (serviceTicket.isExpired()) {
                LOGGER.info("ServiceTicket [{}] has expired.", serviceTicketId);
                throw new InvalidTicketException(serviceTicketId);
            }
            if (!configurationContext.getServiceMatchingStrategy().matches(selectedService, resolvedService)) {
                LOGGER.error("Service ticket [{}] with service [{}] does not match supplied service [{}]", serviceTicketId, serviceTicket.getService().getId(), resolvedService.getId());
                throw new UnrecognizableServiceForServiceTicketValidationException(selectedService);
            }
            serviceTicket.update();
            configurationContext.getTicketRegistry().updateTicket(serviceTicket);
            return serviceTicket;
        }));
        val registeredService = configurationContext.getServicesManager().findServiceBy(selectedService);
        LOGGER.trace("Located registered service definition [{}] from [{}] to handle validation request", registeredService, selectedService);
        RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(selectedService, registeredService);
        val root = serviceTicket.getTicketGrantingTicket().getRoot();
        val authentication = getAuthenticationSatisfiedByPolicy(root.getAuthentication(), new ServiceContext(selectedService, registeredService));
        val principal = authentication.getPrincipal();
        val attributePolicy = Objects.requireNonNull(registeredService.getAttributeReleasePolicy());
        LOGGER.debug("Attribute policy [{}] is associated with service [{}]", attributePolicy, registeredService);
        val context = RegisteredServiceAttributeReleasePolicyContext.builder().registeredService(registeredService).service(selectedService).principal(principal).build();
        val attributesToRelease = attributePolicy.getAttributes(context);
        LOGGER.debug("Calculated attributes for release per the release policy are [{}]", attributesToRelease.keySet());
        val principalId = registeredService.getUsernameAttributeProvider().resolveUsername(principal, selectedService, registeredService);
        val builder = DefaultAuthenticationBuilder.of(principal, configurationContext.getPrincipalFactory(), attributesToRelease, selectedService, registeredService, authentication);
        LOGGER.debug("Principal determined for release to [{}] is [{}]", registeredService.getServiceId(), principalId);
        builder.addAttribute(CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_FROM_NEW_LOGIN, CollectionUtils.wrap(((RenewableServiceTicket) serviceTicket).isFromNewLogin()));
        builder.addAttribute(CasProtocolConstants.VALIDATION_REMEMBER_ME_ATTRIBUTE_NAME, CollectionUtils.wrap(CoreAuthenticationUtils.isRememberMeAuthentication(authentication)));
        val finalAuthentication = builder.build();
        val releasePolicyContext = RegisteredServiceAttributeReleasePolicyContext.builder().registeredService(registeredService).service(service).principal(principal).build();
        val policyAttributes = registeredService.getAttributeReleasePolicy().getAttributes(releasePolicyContext);
        val merger = CoreAuthenticationUtils.getAttributeMerger(PrincipalAttributesCoreProperties.MergingStrategyTypes.MULTIVALUED);
        var accessAttributes = CoreAuthenticationUtils.mergeAttributes(principal.getAttributes(), authentication.getAttributes(), merger);
        accessAttributes = CoreAuthenticationUtils.mergeAttributes(accessAttributes, finalAuthentication.getPrincipal().getAttributes(), merger);
        accessAttributes = CoreAuthenticationUtils.mergeAttributes(accessAttributes, finalAuthentication.getAttributes(), merger);
        accessAttributes = CoreAuthenticationUtils.mergeAttributes(accessAttributes, policyAttributes, merger);
        val accessPrincipal = configurationContext.getPrincipalFactory().createPrincipal(principal.getId(), accessAttributes);
        enforceRegisteredServiceAccess(selectedService, registeredService, accessPrincipal);
        AuthenticationCredentialsThreadLocalBinder.bindCurrent(finalAuthentication);
        val assertion = new DefaultAssertionBuilder(finalAuthentication).with(selectedService).with(serviceTicket.getTicketGrantingTicket().getChainedAuthentications()).with(((RenewableServiceTicket) serviceTicket).isFromNewLogin()).build();
        doPublishEvent(new CasServiceTicketValidatedEvent(this, serviceTicket, assertion));
        return assertion;
    } finally {
        FunctionUtils.doUnchecked(s -> {
            if (serviceTicket.isExpired()) {
                deleteTicket(serviceTicketId);
            } else {
                configurationContext.getTicketRegistry().updateTicket(serviceTicket);
            }
        });
    }
}
Also used : lombok.val(lombok.val) DefaultAssertionBuilder(org.apereo.cas.validation.DefaultAssertionBuilder) ServiceContext(org.apereo.cas.services.ServiceContext) CasServiceTicketValidatedEvent(org.apereo.cas.support.events.ticket.CasServiceTicketValidatedEvent) InvalidTicketException(org.apereo.cas.ticket.InvalidTicketException) UnrecognizableServiceForServiceTicketValidationException(org.apereo.cas.ticket.UnrecognizableServiceForServiceTicketValidationException) RenewableServiceTicket(org.apereo.cas.ticket.RenewableServiceTicket) Audit(org.apereo.inspektr.audit.annotation.Audit)

Example 8 with Audit

use of org.apereo.inspektr.audit.annotation.Audit in project cas by apereo.

the class DefaultAccountRegistrationService method validateToken.

@Audit(action = AuditableActions.ACCOUNT_REGISTRATION, actionResolverName = AuditActionResolvers.ACCOUNT_REGISTRATION_TOKEN_VALIDATION_ACTION_RESOLVER, resourceResolverName = AuditResourceResolvers.ACCOUNT_REGISTRATION_TOKEN_VALIDATION_RESOURCE_RESOLVER)
@Override
public AccountRegistrationRequest validateToken(final String token) throws Exception {
    val claimsJson = this.cipherExecutor.decode(token);
    val claims = JwtClaims.parse(claimsJson);
    val issuer = casProperties.getServer().getPrefix();
    if (!claims.getIssuer().equals(issuer)) {
        LOGGER.error("Token issuer [{}] does not match CAS' [{}]", claims.getIssuer(), issuer);
        return null;
    }
    if (claims.getAudience().isEmpty() || !claims.getAudience().get(0).equals(issuer)) {
        LOGGER.error("Token audience does not match CAS");
        return null;
    }
    if (StringUtils.isBlank(claims.getSubject())) {
        LOGGER.error("Token has no subject identifier");
        return null;
    }
    val props = casProperties.getAccountRegistration().getCore();
    val holder = ClientInfoHolder.getClientInfo();
    if (props.isIncludeServerIpAddress() && !claims.getStringClaimValue("origin").equals(holder.getServerIpAddress())) {
        LOGGER.error("Token origin server IP address does not match CAS");
        return null;
    }
    if (props.isIncludeClientIpAddress() && !claims.getStringClaimValue("client").equals(holder.getClientIpAddress())) {
        LOGGER.error("Token client IP address does not match CAS");
        return null;
    }
    val expirationTime = claims.getExpirationTime();
    if (expirationTime.isBefore(NumericDate.now())) {
        LOGGER.error("Token has expired with expiration time of [{}].", expirationTime);
        return null;
    }
    return new AccountRegistrationRequest(claims.getClaimsMap());
}
Also used : lombok.val(lombok.val) Audit(org.apereo.inspektr.audit.annotation.Audit)

Example 9 with Audit

use of org.apereo.inspektr.audit.annotation.Audit in project cas by apereo.

the class DefaultAccountRegistrationService method createToken.

@Audit(action = AuditableActions.ACCOUNT_REGISTRATION, actionResolverName = AuditActionResolvers.ACCOUNT_REGISTRATION_TOKEN_CREATION_ACTION_RESOLVER, resourceResolverName = AuditResourceResolvers.ACCOUNT_REGISTRATION_TOKEN_CREATION_RESOURCE_RESOLVER)
@Override
public String createToken(final AccountRegistrationRequest registrationRequest) {
    val token = UUID.randomUUID().toString();
    val claims = new JwtClaims();
    claims.setJwtId(token);
    claims.setIssuer(casProperties.getServer().getPrefix());
    claims.setAudience(casProperties.getServer().getPrefix());
    val props = casProperties.getAccountRegistration().getCore();
    val minutes = Beans.newDuration(props.getExpiration()).toMinutes();
    claims.setExpirationTimeMinutesInTheFuture((float) minutes);
    claims.setIssuedAtToNow();
    val holder = ClientInfoHolder.getClientInfo();
    if (holder != null) {
        if (props.isIncludeServerIpAddress()) {
            claims.setStringClaim("origin", holder.getServerIpAddress());
        }
        if (props.isIncludeClientIpAddress()) {
            claims.setStringClaim("client", holder.getClientIpAddress());
        }
    }
    val username = accountRegistrationUsernameBuilder.build(registrationRequest);
    claims.setSubject(username);
    registrationRequest.getProperties().forEach(claims::setClaim);
    LOGGER.debug("Creating account registration token for [{}]", username);
    val json = claims.toJson();
    LOGGER.debug("Encoding the generated JSON token...");
    return this.cipherExecutor.encode(json);
}
Also used : lombok.val(lombok.val) JwtClaims(org.jose4j.jwt.JwtClaims) Audit(org.apereo.inspektr.audit.annotation.Audit)

Example 10 with Audit

use of org.apereo.inspektr.audit.annotation.Audit in project cas by apereo.

the class DefaultSSOSamlHttpRequestExtractor method extract.

@Audit(action = AuditableActions.SAML2_REQUEST, actionResolverName = AuditActionResolvers.SAML2_REQUEST_ACTION_RESOLVER, resourceResolverName = AuditResourceResolvers.SAML2_REQUEST_RESOURCE_RESOLVER)
@Override
@SneakyThrows
public Optional<Pair<? extends SignableSAMLObject, MessageContext>> extract(final HttpServletRequest request, final BaseHttpServletRequestXMLMessageDecoder decoder, final Class<? extends SignableSAMLObject> clazz) {
    LOGGER.trace("Received SAML profile request [{}]", request.getRequestURI());
    decoder.setHttpServletRequest(request);
    decoder.setParserPool(this.parserPool);
    decoder.initialize();
    decoder.decode();
    val messageContext = decoder.getMessageContext();
    LOGGER.trace("Locating SAML object from message context...");
    val object = (SignableSAMLObject) messageContext.getMessage();
    if (object == null) {
        LOGGER.debug("SAML object cannot be determined from the decoder [{}]", decoder.getClass().getSimpleName());
        return Optional.empty();
    }
    if (!clazz.isAssignableFrom(object.getClass())) {
        LOGGER.debug("SAML object [{}] type does not match [{}]", object.getClass().getName(), clazz);
        return Optional.empty();
    }
    LOGGER.debug("Decoded SAML object [{}] from http request", object.getElementQName());
    return Optional.of(Pair.of(object, messageContext));
}
Also used : lombok.val(lombok.val) SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject) Audit(org.apereo.inspektr.audit.annotation.Audit) SneakyThrows(lombok.SneakyThrows)

Aggregations

Audit (org.apereo.inspektr.audit.annotation.Audit)31 lombok.val (lombok.val)21 Counted (com.codahale.metrics.annotation.Counted)4 Metered (com.codahale.metrics.annotation.Metered)4 Timed (com.codahale.metrics.annotation.Timed)4 Principal (org.apereo.cas.authentication.principal.Principal)4 TicketGrantingTicket (org.apereo.cas.ticket.TicketGrantingTicket)4 HashMap (java.util.HashMap)3 AuditActionResolvers (org.apereo.cas.audit.AuditActionResolvers)3 AuditResourceResolvers (org.apereo.cas.audit.AuditResourceResolvers)3 AuditableActions (org.apereo.cas.audit.AuditableActions)3 UnresolvedPrincipalException (org.apereo.cas.authentication.exceptions.UnresolvedPrincipalException)3 NullPrincipal (org.apereo.cas.authentication.principal.NullPrincipal)3 ServiceContext (org.apereo.cas.services.ServiceContext)3 InvalidTicketException (org.apereo.cas.ticket.InvalidTicketException)3 RequiredArgsConstructor (lombok.RequiredArgsConstructor)2 AuditableContext (org.apereo.cas.audit.AuditableContext)2 AuditableExecutionResult (org.apereo.cas.audit.AuditableExecutionResult)2 UsernamePasswordCredential (org.apereo.cas.authentication.UsernamePasswordCredential)2 UnauthorizedProxyingException (org.apereo.cas.services.UnauthorizedProxyingException)2