public CasShibRegisteredService findService(Service service) throws CasShibServiceRegistrarException { if (!isInitialized) { // this shouldn't happen here, but just in case initialize(); } RegisteredService registeredService = servicesManager.findServiceBy(service); if (registeredService instanceof CasShibRegisteredService) { return (CasShibRegisteredService) registeredService; } return null; }
/** * 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; }
@Before public void setUp() { final HttpClient client = mock(HttpClient.class); when(client.isValidEndPoint(any(String.class))).thenReturn(true); when(client.isValidEndPoint(any(URL.class))).thenReturn(true); when(client.sendMessageToEndPoint(any(HttpMessage.class))).thenReturn(true); final ServicesManager servicesManager = mock(ServicesManager.class); this.logoutManager = new LogoutManagerImpl(servicesManager, client, new SamlCompliantLogoutMessageCreator()); this.tgt = mock(TicketGrantingTicket.class); this.services = new HashMap<String, Service>(); this.simpleWebApplicationServiceImpl = new SimpleWebApplicationServiceImpl(URL); this.services.put(ID, this.simpleWebApplicationServiceImpl); when(this.tgt.getServices()).thenReturn(this.services); this.registeredService = new RegisteredServiceImpl(); when(servicesManager.findServiceBy(this.simpleWebApplicationServiceImpl)) .thenReturn(this.registeredService); }
/** * Gets chaining metadata resolver for all saml services. * * @param servicesManager the services manager * @param entityID the entity id * @param resolver the resolver * @return the chaining metadata resolver for all saml services * @throws Exception the exception */ public static MetadataResolver getMetadataResolverForAllSamlServices( final ServicesManager servicesManager, final String entityID, final SamlRegisteredServiceCachingMetadataResolver resolver) throws Exception { final Predicate p = Predicates.instanceOf(SamlRegisteredService.class); final Collection<RegisteredService> registeredServices = servicesManager.findServiceBy(p); final List<MetadataResolver> resolvers = new ArrayList<>(); final ChainingMetadataResolver chainingMetadataResolver = new ChainingMetadataResolver(); for (final RegisteredService registeredService : registeredServices) { final SamlRegisteredService samlRegisteredService = SamlRegisteredService.class.cast(registeredService); final SamlRegisteredServiceServiceProviderMetadataFacade adaptor = SamlRegisteredServiceServiceProviderMetadataFacade.get( resolver, samlRegisteredService, entityID); resolvers.add(adaptor.getMetadataResolver()); } chainingMetadataResolver.setResolvers(resolvers); chainingMetadataResolver.setId(entityID); chainingMetadataResolver.initialize(); return chainingMetadataResolver; }
@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; }