@Override protected Event doExecute(final RequestContext context) throws Exception { final Service service = WebUtils.getService(context); // No service == plain /login request. Return success indicating transition to the login form if (service == null) { return success(); } final RegisteredService registeredService = this.servicesManager.findServiceBy(service); if (registeredService == null) { logger.warn( "Unauthorized Service Access for Service: [ {} ] - service is not defined in the service registry.", service.getId()); throw new UnauthorizedServiceException(); } else if (!registeredService.isEnabled()) { logger.warn( "Unauthorized Service Access for Service: [ {} ] - service is not enabled in the service registry.", service.getId()); if (registeredService instanceof RegisteredServiceWithAttributes) { String disabledServiceUrl = (String) RegisteredServiceWithAttributes.class .cast(registeredService) .getExtraAttributes() .get(DISABLED_SERVICE_URL_ATTRIBUTE); if (disabledServiceUrl != null) { context.getRequestScope().put(DISABLED_SERVICE_URL_ATTRIBUTE, disabledServiceUrl); return no(); } } throw new UnauthorizedServiceException(); } return success(); }
@Override protected Object formBackingObject(final HttpServletRequest request) throws Exception { final String id = request.getParameter("id"); if (!StringUtils.hasText(id)) { // create a default RegisteredServiceImpl object if an explicit class isn't set final Object service; if (this.getCommandClass() != null) { service = this.createCommand(); } else { service = new RegisteredServiceImpl(); } logger.debug("Created new service of type " + service.getClass().getName()); return service; } final RegisteredService service = this.servicesManager.findServiceBy(Long.parseLong(id)); if (service != null) { logger.debug("Loaded service " + service.getServiceId()); } else { logger.debug("Invalid service id specified."); } return service; }
@Override protected Set<Event> resolveInternal(final RequestContext context) { final RegisteredService service = WebUtils.getRegisteredService(context); final Authentication authentication = WebUtils.getAuthentication(context); if (service == null || authentication == null) { logger.debug("No service or authentication is available to determine event for principal"); return null; } final HttpServletRequest request = WebUtils.getHttpServletRequest(context); final String[] values = request.getParameterValues(this.parameterName); if (values != null && values.length > 0) { logger.debug("Received request parameter {} as {}", this.parameterName, values); final Map<String, MultifactorAuthenticationProvider> providerMap = getAllMultifactorAuthenticationProvidersFromApplicationContext(); if (providerMap == null || providerMap.isEmpty()) { logger.warn( "No multifactor authentication providers are available in the application context"); throw new AuthenticationException(); } final Optional<MultifactorAuthenticationProvider> providerFound = providerMap .values() .stream() .filter(provider -> provider.getId().equals(values[0])) .findFirst(); if (providerFound.isPresent()) { if (providerFound.get().verify(service)) { logger.debug( "Attempting to build an event based on the authentication provider [{}] and service [{}]", providerFound.get(), service.getName()); final Event event = validateEventIdForMatchingTransitionInContext( providerFound.get().getId(), context, buildEventAttributeMap( authentication.getPrincipal(), service, providerFound.get())); return ImmutableSet.of(event); } logger.warn( "Located multifactor provider {}, yet the provider cannot be reached or verified", providerFound.get()); return null; } else { logger.warn("No multifactor provider could be found for request parameter {}", values); throw new AuthenticationException(); } } logger.debug("No value could be found for request parameter {}", this.parameterName); return null; }
@Audit( action = "PROXY_GRANTING_TICKET", actionResolverName = "GRANT_PROXY_GRANTING_TICKET_RESOLVER", resourceResolverName = "GRANT_PROXY_GRANTING_TICKET_RESOURCE_RESOLVER") @Timed(name = "GRANT_PROXY_GRANTING_TICKET_TIMER") @Metered(name = "GRANT_PROXY_GRANTING_TICKET_METER") @Counted(name = "GRANT_PROXY_GRANTING_TICKET_COUNTER", monotonic = true) @Transactional(readOnly = false) @Override public TicketGrantingTicket delegateTicketGrantingTicket( final String serviceTicketId, final Credential... credentials) throws AuthenticationException, TicketException { final ServiceTicket serviceTicket = this.serviceTicketRegistry.getTicket(serviceTicketId, ServiceTicket.class); if (serviceTicket == null || serviceTicket.isExpired()) { logger.debug( "ServiceTicket [{}] has expired or cannot be found in the ticket registry", serviceTicketId); throw new InvalidTicketException(serviceTicketId); } final RegisteredService registeredService = this.servicesManager.findServiceBy(serviceTicket.getService()); verifyRegisteredServiceProperties(registeredService, serviceTicket.getService()); if (!registeredService.getProxyPolicy().isAllowedToProxy()) { logger.warn( "ServiceManagement: Service [{}] attempted to proxy, but is not allowed.", serviceTicket.getService().getId()); throw new UnauthorizedProxyingException(); } final Authentication authentication = this.authenticationManager.authenticate(credentials); final String pgtId = this.ticketGrantingTicketUniqueTicketIdGenerator.getNewTicketId( TicketGrantingTicket.PROXY_GRANTING_TICKET_PREFIX); final TicketGrantingTicket proxyGrantingTicket = serviceTicket.grantTicketGrantingTicket( pgtId, authentication, this.ticketGrantingTicketExpirationPolicy); logger.debug( "Generated proxy granting ticket [{}] based off of [{}]", proxyGrantingTicket, serviceTicketId); this.ticketRegistry.addTicket(proxyGrantingTicket); return proxyGrantingTicket; }
/** * Construct SAML response. <a href="http://bit.ly/1uI8Ggu">See this reference for more info.</a> * * @param service the service * @return the SAML response */ protected String constructSamlResponse(final GoogleAccountsService service) { final DateTime currentDateTime = DateTime.parse(new ISOStandardDateFormat().getCurrentDateAndTime()); final DateTime notBeforeIssueInstant = DateTime.parse("2003-04-17T00:46:02Z"); /* * Must be looked up directly from the context * because the services manager is not serializable * and cannot be class field. */ final ApplicationContext context = ApplicationContextProvider.getApplicationContext(); final ServicesManager servicesManager = context.getBean("servicesManager", ServicesManager.class); final RegisteredService registeredService = servicesManager.findServiceBy(service); final String userId = registeredService .getUsernameAttributeProvider() .resolveUsername(service.getPrincipal(), service); final org.opensaml.saml.saml2.core.Response response = samlObjectBuilder.newResponse( samlObjectBuilder.generateSecureRandomId(), currentDateTime, service.getId(), service); response.setStatus(samlObjectBuilder.newStatus(StatusCode.SUCCESS, null)); final AuthnStatement authnStatement = samlObjectBuilder.newAuthnStatement(AuthnContext.PASSWORD_AUTHN_CTX, currentDateTime); final Assertion assertion = samlObjectBuilder.newAssertion( authnStatement, "https://www.opensaml.org/IDP", notBeforeIssueInstant, samlObjectBuilder.generateSecureRandomId()); final Conditions conditions = samlObjectBuilder.newConditions(notBeforeIssueInstant, currentDateTime, service.getId()); assertion.setConditions(conditions); final Subject subject = samlObjectBuilder.newSubject( NameID.EMAIL, userId, service.getId(), currentDateTime, service.getRequestId()); assertion.setSubject(subject); response.getAssertions().add(assertion); final StringWriter writer = new StringWriter(); samlObjectBuilder.marshalSamlXmlObject(response, writer); final String result = writer.toString(); logger.debug("Generated Google SAML response: {}", result); return result; }
@Audit( action = "PROXY_GRANTING_TICKET", actionResolverName = "GRANT_PROXY_GRANTING_TICKET_RESOLVER", resourceResolverName = "GRANT_PROXY_GRANTING_TICKET_RESOURCE_RESOLVER") @Profiled(tag = "GRANT_PROXY_GRANTING_TICKET", logFailuresSeparately = false) @Transactional(readOnly = false) @Override public String delegateTicketGrantingTicket( final String serviceTicketId, final Credential... credentials) throws AuthenticationException, TicketException { Assert.notNull(serviceTicketId, "serviceTicketId cannot be null"); Assert.notNull(credentials, "credentials cannot be null"); final ServiceTicket serviceTicket = this.serviceTicketRegistry.getTicket(serviceTicketId, ServiceTicket.class); if (serviceTicket == null || serviceTicket.isExpired()) { logger.debug( "ServiceTicket [{}] has expired or cannot be found in the ticket registry", serviceTicketId); throw new InvalidTicketException(serviceTicketId); } final RegisteredService registeredService = this.servicesManager.findServiceBy(serviceTicket.getService()); verifyRegisteredServiceProperties(registeredService, serviceTicket.getService()); if (!registeredService.isAllowedToProxy()) { logger.warn( "ServiceManagement: Service [{}] attempted to proxy, but is not allowed.", serviceTicket.getService().getId()); throw new UnauthorizedProxyingException(); } final Authentication authentication = this.authenticationManager.authenticate(credentials); final TicketGrantingTicket ticketGrantingTicket = serviceTicket.grantTicketGrantingTicket( this.ticketGrantingTicketUniqueTicketIdGenerator.getNewTicketId( TicketGrantingTicket.PREFIX), authentication, this.ticketGrantingTicketExpirationPolicy); this.ticketRegistry.addTicket(ticketGrantingTicket); return ticketGrantingTicket.getId(); }
public CasShibRegisteredService findServiceByAppName(String appName) throws CasShibServiceRegistrarException { if (!isInitialized) { // this shouldn't happen here, but just in case initialize(); } for (RegisteredService entry : servicesManager.getAllServices()) { if (entry instanceof CasShibRegisteredService && entry.getName().equals(appName)) { return ((CasShibRegisteredService) entry); } } return null; }
private void clearAllServices() { final Collection<RegisteredService> col = ((OAuth20WrapperController) oauth20WrapperController).getServicesManager().getAllServices(); for (final RegisteredService r : col) { ((OAuth20WrapperController) oauth20WrapperController).getServicesManager().delete(r.getId()); } }
@Override protected Event doExecute(final RequestContext context) throws Exception { final Service service = WebUtils.getService(context); if (service == null) { logger.debug("No service found in the request context, so resuming normally."); return success(); } final RegisteredService registeredService = this.servicesManager.findServiceBy(service); if (registeredService == null) { logger.warn( "Unauthorized Service Access for Service: [{}] - service is not defined in the service registry.", service.getId()); throw new UnauthorizedServiceException(); } if (!registeredService.isEnabled()) { logger.warn( "Unauthorized Service Access for Service: [{}] - service is not enabled in the service registry.", service.getId()); throw new UnauthorizedServiceException(); } if (registeredService instanceof RegisteredServiceWithAttributes) { final RegisteredServiceWithAttributes regSvcWithAttr = RegisteredServiceWithAttributes.class.cast(registeredService); final String redirectToUrl = (String) regSvcWithAttr.getExtraAttributes().get(REDIRECT_TO_URL_ATTRIBUTE); if (redirectToUrl != null && this.redirectionAdvisor.shouldRedirectServiceRequest( context, regSvcWithAttr, redirectToUrl)) { logger.info("Redirecting to url [{}] for service [{}]", redirectToUrl, service.getId()); context.getRequestScope().put(REDIRECT_TO_URL_ATTRIBUTE, redirectToUrl); return yes(); } } logger.debug( "No redirect url is configured, or redirection for service [{}] is not needed", service.getId()); return success(); }
/** * {@inheritDoc} Adds the service to the ServiceRegistry via the ServiceRegistryManager. * * @see * org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse, java.lang.Object, * org.springframework.validation.BindException) */ @Override protected ModelAndView onSubmit( final HttpServletRequest request, final HttpServletResponse response, final Object command, final BindException errors) throws Exception { RegisteredService service = (RegisteredService) command; // only change object class if there isn't an explicit RegisteredService class set if (this.getCommandClass() == null) { // CAS-1071 // Treat _new_ patterns starting with ^ character as a regular expression if (service.getId() == RegisteredService.INITIAL_IDENTIFIER_VALUE && service.getServiceId().startsWith("^")) { logger.debug("Detected regular expression starting with ^"); final RegexRegisteredService regexService = new RegexRegisteredService(); regexService.copyFrom(service); service = regexService; } } this.servicesManager.save(service); logger.info("Saved changes to service " + service.getId()); final ModelAndView modelAndView = new ModelAndView(new RedirectView("manage.html#" + service.getId(), true)); modelAndView.addObject("action", "add"); modelAndView.addObject("id", service.getId()); return modelAndView; }
/** * Determines the principal id to use for a {@link RegisteredService} using the following rules: * * <ul> * <li>If the service is marked to allow anonymous access, a persistent id is returned. * <li>If the {@link org.jasig.cas.services.RegisteredService#getUsernameAttribute()} is blank, * then the default principal id is returned. * <li>If the username attribute is available as part of the principal's attributes, the * corresponding attribute value will be returned. * <li>Otherwise, the default principal's id is returned as the username attribute with an * additional warning. * </ul> * * @param principal The principal object to be validated and constructed * @param registeredService Requesting service for which a principal is being validated. * @param serviceTicket An instance of the service ticket used for validation * @return The principal id to use for the requesting registered service */ private String determinePrincipalIdForRegisteredService( final Principal principal, final RegisteredService registeredService, final ServiceTicket serviceTicket) { String principalId = null; final String serviceUsernameAttribute = registeredService.getUsernameAttribute(); if (registeredService.isAnonymousAccess()) { principalId = this.persistentIdGenerator.generate(principal, serviceTicket.getService()); } else if (StringUtils.isBlank(serviceUsernameAttribute)) { principalId = principal.getId(); } else { if (principal.getAttributes().containsKey(serviceUsernameAttribute)) { principalId = principal.getAttributes().get(serviceUsernameAttribute).toString(); } else { principalId = principal.getId(); final Object[] errorLogParameters = new Object[] { principalId, registeredService.getUsernameAttribute(), principal.getAttributes(), registeredService.getServiceId(), principalId }; logger.warn( "Principal [{}] did not have attribute [{}] among attributes [{}] so CAS cannot " + "provide on the validation response the user attribute the registered service [{}] expects. " + "CAS will instead return the default username attribute [{}]", errorLogParameters); } } logger.debug( "Principal id to return for service [{}] is [{}]. The default principal id is [{}].", new Object[] {registeredService.getName(), principal.getId(), principalId}); return principalId; }
/** * Ensure that the service is found and enabled in the service registry. * * @param registeredService the located entry in the registry * @param service authenticating service * @throws UnauthorizedServiceException */ private void verifyRegisteredServiceProperties( final RegisteredService registeredService, final Service service) { if (registeredService == null) { final String msg = String.format( "ServiceManagement: Unauthorized Service Access. " + "Service [%s] is not found in service registry.", service.getId()); logger.warn(msg); throw new UnauthorizedServiceException( UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, msg); } if (!registeredService.getAccessStrategy().isServiceAccessAllowed()) { final String msg = String.format( "ServiceManagement: Unauthorized Service Access. " + "Service [%s] is not enabled in service registry.", service.getId()); logger.warn(msg); throw new UnauthorizedServiceException( UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, msg); } }
@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) @Transactional(readOnly = false) @Override public Assertion validateServiceTicket(final String serviceTicketId, final Service service) throws TicketException { final RegisteredService registeredService = this.servicesManager.findServiceBy(service); verifyRegisteredServiceProperties(registeredService, service); final ServiceTicket serviceTicket = this.serviceTicketRegistry.getTicket(serviceTicketId, ServiceTicket.class); if (serviceTicket == null) { logger.info("Service ticket [{}] does not exist.", serviceTicketId); throw new InvalidTicketException(serviceTicketId); } try { 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 TicketGrantingTicket root = serviceTicket.getGrantingTicket().getRoot(); final Authentication authentication = getAuthenticationSatisfiedByPolicy( root, new ServiceContext(serviceTicket.getService(), registeredService)); final Principal principal = authentication.getPrincipal(); final AttributeReleasePolicy attributePolicy = registeredService.getAttributeReleasePolicy(); logger.debug( "Attribute policy [{}] is associated with service [{}]", attributePolicy, registeredService); @SuppressWarnings("unchecked") final Map<String, Object> attributesToRelease = attributePolicy != null ? attributePolicy.getAttributes(principal) : Collections.EMPTY_MAP; final String principalId = registeredService.getUsernameAttributeProvider().resolveUsername(principal, service); final Principal modifiedPrincipal = this.principalFactory.createPrincipal(principalId, attributesToRelease); final AuthenticationBuilder builder = AuthenticationBuilder.newInstance(authentication); builder.setPrincipal(modifiedPrincipal); return new ImmutableAssertion( builder.build(), serviceTicket.getGrantingTicket().getChainedAuthentications(), serviceTicket.getService(), serviceTicket.isFromNewLogin()); } finally { if (serviceTicket.isExpired()) { this.serviceTicketRegistry.deleteTicket(serviceTicketId); } } }
@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) @Transactional(readOnly = false) @Override public ServiceTicket grantServiceTicket( final String ticketGrantingTicketId, final Service service, final Credential... credentials) throws AuthenticationException, TicketException { final TicketGrantingTicket ticketGrantingTicket = getTicket(ticketGrantingTicketId, TicketGrantingTicket.class); final RegisteredService registeredService = this.servicesManager.findServiceBy(service); verifyRegisteredServiceProperties(registeredService, service); final Set<Credential> sanitizedCredentials = sanitizeCredentials(credentials); Authentication currentAuthentication = null; if (sanitizedCredentials.size() > 0) { currentAuthentication = this.authenticationManager.authenticate( sanitizedCredentials.toArray(new Credential[] {})); final Authentication original = ticketGrantingTicket.getAuthentication(); if (!currentAuthentication.getPrincipal().equals(original.getPrincipal())) { throw new MixedPrincipalException( currentAuthentication, currentAuthentication.getPrincipal(), original.getPrincipal()); } ticketGrantingTicket.getSupplementalAuthentications().add(currentAuthentication); } if (currentAuthentication == null && !registeredService.getAccessStrategy().isServiceAccessAllowedForSso()) { logger.warn("ServiceManagement: Service [{}] is not allowed to use SSO.", service.getId()); throw new UnauthorizedSsoServiceException(); } final Service proxiedBy = ticketGrantingTicket.getProxiedBy(); if (proxiedBy != null) { logger.debug( "TGT is proxied by [{}]. Locating proxy service in registry...", proxiedBy.getId()); final RegisteredService proxyingService = servicesManager.findServiceBy(proxiedBy); if (proxyingService != null) { logger.debug("Located proxying service [{}] in the service registry", proxyingService); if (!proxyingService.getProxyPolicy().isAllowedToProxy()) { logger.warn( "Found proxying service {}, but it is not authorized to fulfill the proxy attempt made by {}", proxyingService.getId(), service.getId()); throw new UnauthorizedProxyingException( "Proxying is not allowed for registered service " + registeredService.getId()); } } else { logger.warn( "No proxying service found. Proxy attempt by service [{}] (registered service [{}]) is not allowed.", service.getId(), registeredService.getId()); throw new UnauthorizedProxyingException( "Proxying is not allowed for registered service " + registeredService.getId()); } } else { logger.trace("TGT is not proxied by another service"); } // Perform security policy check by getting the authentication that satisfies the configured // policy // This throws if no suitable policy is found getAuthenticationSatisfiedByPolicy( ticketGrantingTicket, new ServiceContext(service, registeredService)); final List<Authentication> authentications = ticketGrantingTicket.getChainedAuthentications(); final Principal principal = authentications.get(authentications.size() - 1).getPrincipal(); final Map<String, Object> principalAttrs = registeredService.getAttributeReleasePolicy().getAttributes(principal); if (!registeredService .getAccessStrategy() .doPrincipalAttributesAllowServiceAccess(principalAttrs)) { logger.warn( "ServiceManagement: Cannot grant service ticket because Service [{}] is not authorized for use by [{}].", service.getId(), principal); throw new UnauthorizedServiceForPrincipalException(); } final String uniqueTicketIdGenKey = service.getClass().getName(); logger.debug("Looking up service ticket id generator for [{}]", uniqueTicketIdGenKey); UniqueTicketIdGenerator serviceTicketUniqueTicketIdGenerator = this.uniqueTicketIdGeneratorsForService.get(uniqueTicketIdGenKey); if (serviceTicketUniqueTicketIdGenerator == null) { serviceTicketUniqueTicketIdGenerator = this.defaultServiceTicketIdGenerator; logger.debug( "Service ticket id generator not found for [{}]. Using the default generator...", uniqueTicketIdGenKey); } final String ticketPrefix = authentications.size() == 1 ? ServiceTicket.PREFIX : ServiceTicket.PROXY_TICKET_PREFIX; final String ticketId = serviceTicketUniqueTicketIdGenerator.getNewTicketId(ticketPrefix); final ServiceTicket serviceTicket = ticketGrantingTicket.grantServiceTicket( ticketId, service, this.serviceTicketExpirationPolicy, currentAuthentication != null); this.serviceTicketRegistry.addTicket(serviceTicket); logger.info( "Granted ticket [{}] for service [{}] for user [{}]", serviceTicket.getId(), service.getId(), principal.getId()); return serviceTicket; }
@Audit( action = "SERVICE_TICKET", actionResolverName = "GRANT_SERVICE_TICKET_RESOLVER", resourceResolverName = "GRANT_SERVICE_TICKET_RESOURCE_RESOLVER") @Profiled(tag = "GRANT_SERVICE_TICKET", logFailuresSeparately = false) @Transactional(readOnly = false) @Override public String grantServiceTicket( final String ticketGrantingTicketId, final Service service, final Credential... credentials) throws AuthenticationException, TicketException { Assert.notNull(ticketGrantingTicketId, "ticketGrantingticketId cannot be null"); Assert.notNull(service, "service cannot be null"); final TicketGrantingTicket ticketGrantingTicket = this.ticketRegistry.getTicket(ticketGrantingTicketId, TicketGrantingTicket.class); if (ticketGrantingTicket == null) { logger.debug( "TicketGrantingTicket [{}] cannot be found in the ticket registry.", ticketGrantingTicketId); throw new InvalidTicketException(ticketGrantingTicketId); } synchronized (ticketGrantingTicket) { if (ticketGrantingTicket.isExpired()) { this.ticketRegistry.deleteTicket(ticketGrantingTicketId); logger.debug( "TicketGrantingTicket[{}] has expired and is now deleted from the ticket registry.", ticketGrantingTicketId); throw new InvalidTicketException(ticketGrantingTicketId); } } final RegisteredService registeredService = this.servicesManager.findServiceBy(service); verifyRegisteredServiceProperties(registeredService, service); if (!registeredService.isSsoEnabled() && credentials == null && ticketGrantingTicket.getCountOfUses() > 0) { logger.warn("ServiceManagement: Service [{}] is not allowed to use SSO.", service.getId()); throw new UnauthorizedSsoServiceException(); } // CAS-1019 final List<Authentication> authns = ticketGrantingTicket.getChainedAuthentications(); if (authns.size() > 1) { if (!registeredService.isAllowedToProxy()) { final String message = String.format( "ServiceManagement: Proxy attempt by service [%s] (registered service [%s]) is not allowed.", service.getId(), registeredService.toString()); logger.warn(message); throw new UnauthorizedProxyingException(message); } } if (credentials != null) { final Authentication current = this.authenticationManager.authenticate(credentials); final Authentication original = ticketGrantingTicket.getAuthentication(); if (!current.getPrincipal().equals(original.getPrincipal())) { throw new MixedPrincipalException(current, current.getPrincipal(), original.getPrincipal()); } ticketGrantingTicket.getSupplementalAuthentications().add(current); } // Perform security policy check by getting the authentication that satisfies the configured // policy // This throws if no suitable policy is found getAuthenticationSatisfiedByPolicy( ticketGrantingTicket, new ServiceContext(service, registeredService)); final String uniqueTicketIdGenKey = service.getClass().getName(); if (!this.uniqueTicketIdGeneratorsForService.containsKey(uniqueTicketIdGenKey)) { logger.warn( "Cannot create service ticket because the key [{}] for service [{}] is not linked to a ticket id generator", uniqueTicketIdGenKey, service.getId()); throw new UnauthorizedSsoServiceException(); } final UniqueTicketIdGenerator serviceTicketUniqueTicketIdGenerator = this.uniqueTicketIdGeneratorsForService.get(uniqueTicketIdGenKey); final String generatedServiceTicketId = serviceTicketUniqueTicketIdGenerator.getNewTicketId(ServiceTicket.PREFIX); logger.debug( "Generated service ticket id [{}] for ticket granting ticket [{}]", generatedServiceTicketId, ticketGrantingTicket.getId()); final ServiceTicket serviceTicket = ticketGrantingTicket.grantServiceTicket( generatedServiceTicketId, service, this.serviceTicketExpirationPolicy, credentials != null); this.serviceTicketRegistry.addTicket(serviceTicket); if (logger.isInfoEnabled()) { final List<Authentication> authentications = serviceTicket.getGrantingTicket().getChainedAuthentications(); final String formatString = "Granted %s ticket [%s] for service [%s] for user [%s]"; final String type; final String principalId = authentications.get(authentications.size() - 1).getPrincipal().getId(); if (authentications.size() == 1) { type = "service"; } else { type = "proxy"; } logger.info( String.format(formatString, type, serviceTicket.getId(), service.getId(), principalId)); } return serviceTicket.getId(); }