/** {@inheritDoc} */ @Override @Nullable public List<Assertion> apply(@Nullable final ProfileRequestContext input) { if (input != null && input.getOutboundMessageContext() != null) { final Object outboundMessage = input.getOutboundMessageContext().getMessage(); if (outboundMessage == null) { return null; } else if (outboundMessage instanceof Assertion) { return Collections.singletonList((Assertion) outboundMessage); } else if (outboundMessage instanceof Response) { return ((Response) outboundMessage).getAssertions(); } } return null; } }
if (samlResponse.getStatus() == null || samlResponse.getStatus().getStatusCode() == null || samlResponse.getStatus().getStatusCode().getValue() == null) { LOG.fine("Either the SAML Response Status or StatusCode is null"); throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity"); String statusValue = samlResponse.getStatus().getStatusCode().getValue().getLocalPart(); if (!SAML1_STATUSCODE_SUCCESS.equals(statusValue)) { LOG.fine( "SAML Status code of " + samlResponse.getStatus().getStatusCode().getValue() + "does not equal " + SAML1_STATUSCODE_SUCCESS ); if (samlResponse.getIssueInstant() != null) { DateTime currentTime = new DateTime(); currentTime = currentTime.plusSeconds(futureTTL); if (samlResponse.getIssueInstant().isAfter(currentTime)) { LOG.fine("SAML Response IssueInstant not met"); throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity"); if (SAMLVersion.VERSION_11 != samlResponse.getVersion()) { LOG.fine( "SAML Version of " + samlResponse.getVersion() + "does not equal " + SAMLVersion.VERSION_11 ); for (org.opensaml.saml.saml1.core.Assertion assertion : samlResponse.getAssertions()) { SamlAssertionWrapper wrapper = new SamlAssertionWrapper(assertion); validateAssertion(
/** {@inheritDoc} */ protected void processChildElement(XMLObject parentSAMLObject, XMLObject childSAMLObject) throws UnmarshallingException { Response response = (Response) parentSAMLObject; if (childSAMLObject instanceof Assertion) { response.getAssertions().add((Assertion) childSAMLObject); } else if (childSAMLObject instanceof Status) { response.setStatus((Status) childSAMLObject); } else { super.processChildElement(parentSAMLObject, childSAMLObject); } }
/** * Create a new SAML response object. * @param id the id * @param issueInstant the issue instant * @param recipient the recipient * @param service the service * @return the response */ public Response newResponse(final String id, final DateTime issueInstant, final String recipient, final WebApplicationService service) { final Response samlResponse = newSamlObject(Response.class); samlResponse.setID(id); samlResponse.setIssueInstant(issueInstant); samlResponse.setVersion(SAMLVersion.VERSION_11); samlResponse.setInResponseTo(recipient); if (service instanceof SamlService) { final SamlService samlService = (SamlService) service; final String requestId = samlService.getRequestID(); if (StringUtils.isNotBlank(requestId)) { samlResponse.setInResponseTo(requestId); } } return samlResponse; }
/** * Validate the Response signature (if it exists) */ private void validateResponseSignature( org.opensaml.saml.saml1.core.Response samlResponse, Crypto sigCrypto, CallbackHandler callbackHandler ) throws WSSecurityException { if (!samlResponse.isSigned()) { return; } // Required to make IdResolver happy in OpenSAML Attr idAttr = samlResponse.getDOM().getAttributeNodeNS(null, "ID"); if (idAttr != null) { samlResponse.getDOM().setIdAttributeNode(idAttr, true); } validateResponseSignature( samlResponse.getSignature(), samlResponse.getDOM().getOwnerDocument(), sigCrypto, callbackHandler ); }
@Override protected void prepareResponse(final Response response, final Map<String, Object> model) { val issuedAt = DateTimeUtils.zonedDateTimeOf(response.getIssueInstant()); val service = getAssertionFrom(model).getService(); LOGGER.debug("Preparing SAML response for service [{}]", service); response.setStatus(this.samlObjectBuilder.newStatus(StatusCode.SUCCESS, null)); LOGGER.debug("Set response status code to [{}]", response.getStatus()); response.getAssertions().add(assertion);
response.setID(request.getTicket()); response.setIssueInstant(DateTime.now()); final Status status = newSAMLObject(Status.class, Status.DEFAULT_ELEMENT_NAME); final StatusCode code = newSAMLObject(StatusCode.class, StatusCode.DEFAULT_ELEMENT_NAME); code.setValue(StatusCode.SUCCESS); status.setStatusCode(code); response.setStatus(status); response.getAssertions().add(assertion); return response;
@Override protected void prepareResponse(final Response response, final Map<String, Object> model) { final DateTime issuedAt = response.getIssueInstant(); final Service service = getAssertionFrom(model).getService(); final Authentication authentication = getPrimaryAuthenticationFrom(model); final String authenticationMethod = (String) authentication.getAttributes().get( SamlAuthenticationMetaDataPopulator.ATTRIBUTE_AUTHENTICATION_METHOD); final AuthenticationStatement authnStatement = this.samlObjectBuilder.newAuthenticationStatement( authentication.getAuthenticationDate().toDate(), authenticationMethod, getPrincipal(model).getId()); final Assertion assertion = this.samlObjectBuilder.newAssertion(authnStatement, this.issuer, issuedAt, this.samlObjectBuilder.generateSecureRandomId()); final Conditions conditions = this.samlObjectBuilder.newConditions(issuedAt, service.getId(), this.issueLength); assertion.setConditions(conditions); final Subject subject = this.samlObjectBuilder.newSubject(getPrincipal(model).getId()); final Map<String, Object> attributesToSend = prepareSamlAttributes(model, service); if (!attributesToSend.isEmpty()) { assertion.getAttributeStatements().add(this.samlObjectBuilder.newAttributeStatement( subject, attributesToSend, VALIDATION_SAML_ATTRIBUTE_NAMESPACE)); } response.setStatus(this.samlObjectBuilder.newStatus(StatusCode.SUCCESS, null)); response.getAssertions().add(assertion); }
/** * Constructs and adds a {@link Assertion} to the given {@link Response}. The {@link Assertion} is constructed * using the parameters supplied, and its issue instant is set to the issue instant of the given {@link Response}. * * @param action the current action * @param response the response to which the assertion will be added * @param idGenerator source of assertion ID * @param issuer value for assertion * * @return the assertion that was added to the response */ @Nonnull public static Assertion addAssertionToResponse(@Nonnull final AbstractProfileAction action, @Nonnull final Response response, @Nonnull final IdentifierGenerationStrategy idGenerator, @Nonnull @NotEmpty final String issuer) { final Assertion assertion = buildAssertion(action, idGenerator, issuer); assertion.setIssueInstant(response.getIssueInstant()); getLogger().debug("Profile Action {}: Added Assertion {} to Response {}", new Object[] {action.getClass().getSimpleName(), assertion.getID(), response.getID(),}); response.getAssertions().add(assertion); return assertion; }
/** {@inheritDoc} */ @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) { if (response instanceof org.opensaml.saml.saml1.core.Response) { for (final org.opensaml.saml.saml1.core.Assertion assertion : ((org.opensaml.saml.saml1.core.Response) response).getAssertions()) { log.debug("{} Added NotBefore condition to Assertion {}", getLogPrefix(), assertion.getID()); SAML1ActionSupport.addConditionsToAssertion(this, assertion).setNotBefore( ((org.opensaml.saml.saml1.core.Response) response).getIssueInstant()); } } else if (response instanceof org.opensaml.saml.saml2.core.Response) { for (final org.opensaml.saml.saml2.core.Assertion assertion : ((org.opensaml.saml.saml2.core.Response) response).getAssertions()) { log.debug("{} Added NotBefore condition to Assertion {}", getLogPrefix(), assertion.getID()); SAML2ActionSupport.addConditionsToAssertion(this, assertion).setNotBefore( ((org.opensaml.saml.saml2.core.Response) response).getIssueInstant()); } } }
/** {@inheritDoc} */ @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) { final XMLObjectBuilderFactory bf = XMLObjectProviderRegistrySupport.getBuilderFactory(); final SAMLObjectBuilder<StatusCode> statusCodeBuilder = (SAMLObjectBuilder<StatusCode>) bf.<StatusCode>getBuilderOrThrow(StatusCode.DEFAULT_ELEMENT_NAME); final SAMLObjectBuilder<Status> statusBuilder = (SAMLObjectBuilder<Status>) bf.<Status>getBuilderOrThrow(Status.DEFAULT_ELEMENT_NAME); final SAMLObjectBuilder<Response> responseBuilder = (SAMLObjectBuilder<Response>) bf.<Response>getBuilderOrThrow(Response.DEFAULT_ELEMENT_NAME); final StatusCode statusCode = statusCodeBuilder.buildObject(); statusCode.setValue(StatusCode.SUCCESS); final Status status = statusBuilder.buildObject(); status.setStatusCode(statusCode); final Response response = responseBuilder.buildObject(); response.setID(idGenerator.generateIdentifier()); response.setIssueInstant(new DateTime(ISOChronology.getInstanceUTC())); response.setStatus(status); response.setVersion(SAMLVersion.VERSION_11); profileRequestContext.getOutboundMessageContext().setMessage(response); }
@Nonnull @Override protected Response buildSamlResponse( @Nonnull final RequestContext springRequestContext, @Nonnull final ProfileRequestContext<SAMLObject, SAMLObject> profileRequestContext) { final TicketValidationRequest request = getCASRequest(profileRequestContext); final TicketValidationResponse validationResponse = getCASResponse(profileRequestContext); final Response response = newSAMLObject(Response.class, Response.DEFAULT_ELEMENT_NAME); response.setID(request.getTicket()); response.setIssueInstant(DateTime.now()); final Status status = newSAMLObject(Status.class, Status.DEFAULT_ELEMENT_NAME); final StatusCode statusCode = newSAMLObject(StatusCode.class, StatusCode.DEFAULT_ELEMENT_NAME); statusCode.setValue(new QName(NAMESPACE, validationResponse.getErrorCode())); status.setStatusCode(statusCode); final StatusMessage message = newSAMLObject(StatusMessage.class, StatusMessage.DEFAULT_ELEMENT_NAME); message.setMessage(validationResponse.getErrorDetail()); status.setStatusMessage(message); response.setStatus(status); return response; } }
private static void signXMLObject(XMLObject xmlObject) throws WSSecurityException { if (xmlObject instanceof org.opensaml.saml.saml1.core.Response) { org.opensaml.saml.saml1.core.Response response = (org.opensaml.saml.saml1.core.Response)xmlObject; // Sign any Assertions if (response.getAssertions() != null) { for (org.opensaml.saml.saml1.core.Assertion assertion : response.getAssertions()) { signObject(assertion.getSignature()); } } signObject(response.getSignature()); } else if (xmlObject instanceof org.opensaml.saml.saml2.core.Response) { org.opensaml.saml.saml2.core.Response response = (org.opensaml.saml.saml2.core.Response)xmlObject; // Sign any Assertions if (response.getAssertions() != null) { for (org.opensaml.saml.saml2.core.Assertion assertion : response.getAssertions()) { signObject(assertion.getSignature()); } } signObject(response.getSignature()); } else if (xmlObject instanceof SignableSAMLObject) { signObject(((SignableSAMLObject)xmlObject).getSignature()); } }
/** * Resolve the SAML entity ID from a SAML 1 response. * * @param response the response * * @return the entity ID, or null if it could not be resolved */ @Nullable protected String processSaml1Response(@Nonnull final org.opensaml.saml.saml1.core.Response response) { String issuer = null; final List<Assertion> assertions = response.getAssertions(); if (assertions != null && assertions.size() > 0) { log.info("Attempting to extract issuer from enclosed SAML 1.x Assertion(s)"); for (Assertion assertion : assertions) { if (assertion != null && assertion.getIssuer() != null) { if (issuer != null && !issuer.equals(assertion.getIssuer())) { log.warn("SAML 1.x assertions, within response '{}' contain different issuer IDs, " + "can not dynamically resolve SAML peer entity ID", response.getID()); return null; } issuer = assertion.getIssuer(); } } } if (issuer == null) { log.warn("Issuer could not be extracted from standard SAML 1.x response message"); } return issuer; }
/** {@inheritDoc} */ @Override @Nullable public String apply(@Nullable final ProfileRequestContext input) { final SAMLObject response = responseLookupStrategy.apply(input); if (response != null) { if (response instanceof Response) { final org.opensaml.saml.saml1.core.StatusMessage msg = ((Response) response).getStatus() != null ? ((Response) response).getStatus().getStatusMessage() : null; if (msg != null) { return msg.getMessage(); } } else if (response instanceof StatusResponseType) { final org.opensaml.saml.saml2.core.StatusMessage msg = ((StatusResponseType) response).getStatus() != null ? ((StatusResponseType) response).getStatus().getStatusMessage() : null; if (msg != null) { return msg.getMessage(); } } } return null; }
@Override protected void prepareResponse(final Response response, final Map<String, Object> model) { response.setStatus(this.samlObjectBuilder.newStatus(StatusCode.REQUEST_DENIED, (String) model.get("description"))); } }
/** {@inheritDoc} */ @Override @Nullable public String apply(@Nullable final ProfileRequestContext input) { final SAMLObject response = responseLookupStrategy.apply(input); if (response != null) { if (response instanceof Response) { final org.opensaml.saml.saml1.core.StatusCode sc = ((Response) response).getStatus() != null ? ((Response) response).getStatus().getStatusCode() : null; if (sc != null && sc.getValue() != null) { return sc.getValue().getLocalPart(); } } else if (response instanceof StatusResponseType) { final org.opensaml.saml.saml2.core.StatusCode sc = ((StatusResponseType) response).getStatus() != null ? ((StatusResponseType) response).getStatus().getStatusCode() : null; if (sc != null) { return sc.getValue(); } } } return null; }
@Override protected void prepareResponse(final Response response, final Map<String, Object> model) { response.setStatus(this.samlObjectBuilder.newStatus(StatusCode.REQUEST_DENIED, (String) model.get("description"))); } }
/** {@inheritDoc} */ @Override protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) { log.debug("{} Attempting to add DoNotCache condition to every Assertion in Response", getLogPrefix()); response = responseLookupStrategy.apply(profileRequestContext); if (response == null) { log.debug("{} No SAML response located in current profile request context", getLogPrefix()); ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX); return false; } else if (response.getAssertions().isEmpty()) { log.debug("{} No assertions in response message, nothing to do", getLogPrefix()); return false; } return super.doPreExecute(profileRequestContext); }
/** * Get whether the message is a SAML response containing an error status. * * @param message message to check * * @return true iff the message is a SAML response containing an error status */ private boolean isErrorResponse(@Nullable final Object message) { if (message != null) { if (message instanceof Response) { if (((Response) message).getStatus() != null) { final org.opensaml.saml.saml1.core.StatusCode s1 = ((Response) message).getStatus().getStatusCode(); return s1 != null && s1.getValue() != null && !org.opensaml.saml.saml1.core.StatusCode.SUCCESS.equals(s1.getValue()); } } else if (message instanceof StatusResponseType) { if (((StatusResponseType) message).getStatus() != null) { final org.opensaml.saml.saml2.core.StatusCode s2 = ((StatusResponseType) message).getStatus().getStatusCode(); return s2 != null && s2.getValue() != null && !org.opensaml.saml.saml2.core.StatusCode.SUCCESS.equals(s2.getValue()); } } } return false; }