/** * 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 = "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); } } }