private void buildCommonAttributes(String localEntityId, Response response, Endpoint service, AuthnRequest authnRequest) { response.setID(generateID()); response.setIssuer(getIssuer(localEntityId)); response.setInResponseTo(authnRequest.getID()); response.setVersion(SAMLVersion.VERSION_20); response.setIssueInstant(new DateTime()); if (service != null) { response.setDestination(service.getLocation()); } }
/** {@inheritDoc} */ protected void processAttribute(XMLObject samlObject, Attr attribute) throws UnmarshallingException { Endpoint endpoint = (Endpoint) samlObject; if (attribute.getLocalName().equals(Endpoint.BINDING_ATTRIB_NAME)) { endpoint.setBinding(attribute.getValue()); } else if (attribute.getLocalName().equals(Endpoint.LOCATION_ATTRIB_NAME)) { endpoint.setLocation(attribute.getValue()); } else if (attribute.getLocalName().equals(Endpoint.RESPONSE_LOCATION_ATTRIB_NAME)) { endpoint.setResponseLocation(attribute.getValue()); } else { QName attribQName = XMLHelper.getNodeQName(attribute); if (attribute.isId()) { endpoint.getUnknownAttributes().registerID(attribQName); } endpoint.getUnknownAttributes().put(attribQName, attribute.getValue()); } }
/** {@inheritDoc} */ public void marshallAttributes(XMLObject samlElement, Element domElement) { Endpoint endpoint = (Endpoint) samlElement; if (endpoint.getBinding() != null) { domElement.setAttributeNS(null, Endpoint.BINDING_ATTRIB_NAME, endpoint.getBinding().toString()); } if (endpoint.getLocation() != null) { domElement.setAttributeNS(null, Endpoint.LOCATION_ATTRIB_NAME, endpoint.getLocation().toString()); } if (endpoint.getResponseLocation() != null) { domElement.setAttributeNS(null, Endpoint.RESPONSE_LOCATION_ATTRIB_NAME, endpoint.getResponseLocation() .toString()); } Attr attribute; for (Entry<QName, String> entry : endpoint.getUnknownAttributes().entrySet()) { attribute = XMLHelper.constructAttribute(domElement.getOwnerDocument(), entry.getKey()); attribute.setValue(entry.getValue()); domElement.setAttributeNodeNS(attribute); if (Configuration.isIDAttribute(entry.getKey()) || endpoint.getUnknownAttributes().isIDAttribute(entry.getKey())) { attribute.getOwnerElement().setIdAttributeNode(attribute, true); } } } }
/** * Verifies that the destination URL intended in the message matches with the endpoint address. The URL message * was ultimately received doesn't need to necessarily match the one defined in the metadata (in case of e.g. reverse-proxying * of messages). * * @param endpoint endpoint the message was received at * @param destination URL of the endpoint the message was intended to be sent to by the peer or null when not included * @throws SAMLException in case endpoint doesn't match */ protected void verifyEndpoint(Endpoint endpoint, String destination) throws SAMLException { // Verify that destination in the response matches one of the available endpoints if (destination != null) { if (uriComparator.compare(destination, endpoint.getLocation())) { // Expected } else if (uriComparator.compare(destination, endpoint.getResponseLocation())) { // Expected } else { throw new SAMLException("Intended destination " + destination + " doesn't match any of the endpoint URLs on endpoint " + endpoint.getLocation() + " for profile " + getProfileIdentifier()); } } }
@Override public SAMLMessageContext sendMessage(SAMLMessageContext samlContext, boolean sign) throws SAMLException, MetadataProviderException, MessageEncodingException { Endpoint endpoint = samlContext.getPeerEntityEndpoint(); SAMLBinding binding = getBinding(endpoint); samlContext.setLocalEntityId(spConfiguration.getEntityId()); samlContext.getLocalEntityMetadata().setEntityID(spConfiguration.getEntityId()); samlContext.getPeerEntityEndpoint().setLocation(spConfiguration.getIdpSSOServiceURL()); SPSSODescriptor roleDescriptor = (SPSSODescriptor) samlContext.getLocalEntityMetadata().getRoleDescriptors().get(0); AssertionConsumerService assertionConsumerService = roleDescriptor.getAssertionConsumerServices().stream().filter(service -> service.isDefault()).findAny().orElseThrow(() -> new RuntimeException("No default ACS")); assertionConsumerService.setBinding(spConfiguration.getProtocolBinding()); assertionConsumerService.setLocation(spConfiguration.getAssertionConsumerServiceURL()); return super.sendMessage(samlContext, spConfiguration.isNeedsSigning(), binding); } }
.getBuilder(AssertionConsumerService.DEFAULT_ELEMENT_NAME); Endpoint samlEndpoint = endpointBuilder.buildObject(); samlEndpoint.setLocation(idpEndpoint); samlEndpoint.setResponseLocation(spDestination);
while (endpointItr.hasNext()) { endpoint = endpointItr.next(); if (!getSupportedIssuerBindings().contains(endpoint.getBinding())) { log.debug("Removing endpoint {} because its binding {} is not supported", endpoint.getLocation(), endpoint.getBinding()); endpointItr.remove(); continue; if (filterByRequestBinding && !endpoint.getBinding().equals(acsBinding)) { log.debug("Removing endpoint {} because its binding {} does not match request's requested binding", endpoint.getLocation(), endpoint.getBinding()); endpointItr.remove();
/** * Method determines binding supported by the given endpoint. Usually the biding is encoded in the binding attribute * of the endpoint, but in some cases more processing is needed (e.g. for HoK profile). * * @param endpoint endpoint * @return binding supported by the endpoint */ public static String getBindingForEndpoint(Endpoint endpoint) { String bindingName = endpoint.getBinding(); // For HoK profile the used binding is determined in a different way if (org.springframework.security.saml.SAMLConstants.SAML2_HOK_WEBSSO_PROFILE_URI.equals(bindingName)) { QName attributeName = org.springframework.security.saml.SAMLConstants.WEBSSO_HOK_METADATA_ATT_NAME; String endpointLocation = endpoint.getUnknownAttributes().get(attributeName); if (endpointLocation != null) { bindingName = endpointLocation; } else { throw new SAMLRuntimeException("Holder of Key profile endpoint doesn't contain attribute hoksso:ProtocolBinding"); } } return bindingName; }
/** * Filters the list of possible endpoints by supported outbound bindings. * * @param endpoints raw list of endpoints * * @return filtered endpoints */ protected List<? extends Endpoint> filterEndpointsByProtocolBinding(List<? extends Endpoint> endpoints) { List<Endpoint> filteredEndpoints = new ArrayList<Endpoint>(endpoints); Iterator<Endpoint> endpointItr = filteredEndpoints.iterator(); Endpoint endpoint; while (endpointItr.hasNext()) { endpoint = endpointItr.next(); if (!getSupportedIssuerBindings().contains(endpoint.getBinding())) { endpointItr.remove(); continue; } } return filteredEndpoints; }
if (endpoint.getLocation() != null && uriComparator.compare(endpoint.getLocation(), requestURL)) { log.debug("Found endpoint {} for request URL {} based on location attribute in metadata", endpoint, requestURL); return endpoint; } else if (endpoint.getResponseLocation() != null && uriComparator.compare(endpoint.getResponseLocation(), requestURL)) { log.debug("Found endpoint {} for request URL {} based on response location attribute in metadata", endpoint, requestURL); return endpoint;
public void doSAMLRedirect(final HttpServletResponse response, final String relayState) throws SAMLException, MessageEncodingException { final String requestId = SAMLUtils.generateRequestId(); final AuthnRequest authnRequest = createAuthnRequest(requestId); final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter(response, true); final BasicSAMLMessageContext<SAMLObject, AuthnRequest, SAMLObject> context = new BasicSAMLMessageContext<>(); final Endpoint endpoint = new SingleSignOnServiceBuilder().buildObject(); endpoint.setLocation(getIdPConfig().getLoginUrl()); context.setPeerEntityEndpoint(endpoint); context.setOutboundSAMLMessage(authnRequest); context.setOutboundSAMLMessageSigningCredential(authnRequest.getSignature().getSigningCredential()); context.setOutboundMessageTransport(responseAdapter); context.setRelayState(relayState == null ? "/" : relayState); final HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); encoder.encode(context); }
/** * Checks that Binding is present. * * @param endpoint * @throws ValidationException */ protected void validateBinding(Endpoint endpoint) throws ValidationException { if (DatatypeHelper.isEmpty(endpoint.getBinding())) { throw new ValidationException("Binding required"); } }
&& !DatatypeHelper.isEmpty(endpoint.getResponseLocation())) { urlBuilder = new URLBuilder(endpoint.getResponseLocation()); } else { if (DatatypeHelper.isEmpty(endpoint.getLocation())) { throw new MessageEncodingException("Relying party endpoint location was null or empty."); urlBuilder = new URLBuilder(endpoint.getLocation());
@SuppressWarnings("unchecked") public void sendAuthnResponse(SAMLPrincipal principal, HttpServletResponse response) throws MarshallingException, SignatureException, MessageEncodingException { Status status = buildStatus(StatusCode.SUCCESS_URI); String entityId = idpConfiguration.getEntityId(); Credential signingCredential = resolveCredential(entityId); Response authResponse = buildSAMLObject(Response.class, Response.DEFAULT_ELEMENT_NAME); Issuer issuer = buildIssuer(entityId); authResponse.setIssuer(issuer); authResponse.setID(SAMLBuilder.randomSAMLId()); authResponse.setIssueInstant(new DateTime()); authResponse.setInResponseTo(principal.getRequestID()); Assertion assertion = buildAssertion(principal, status, entityId); signAssertion(assertion, signingCredential); authResponse.getAssertions().add(assertion); authResponse.setDestination(principal.getAssertionConsumerServiceURL()); authResponse.setStatus(status); Endpoint endpoint = buildSAMLObject(Endpoint.class, SingleSignOnService.DEFAULT_ELEMENT_NAME); endpoint.setLocation(principal.getAssertionConsumerServiceURL()); HttpServletResponseAdapter outTransport = new HttpServletResponseAdapter(response, false); BasicSAMLMessageContext messageContext = new BasicSAMLMessageContext(); messageContext.setOutboundMessageTransport(outTransport); messageContext.setPeerEntityEndpoint(endpoint); messageContext.setOutboundSAMLMessage(authResponse); messageContext.setOutboundSAMLMessageSigningCredential(signingCredential); messageContext.setOutboundMessageIssuer(entityId); messageContext.setRelayState(principal.getRelayState()); encoder.encode(messageContext); }
/** * Checks that Location is present. * * @param endpoint * @throws ValidationException */ protected void validateLocation(Endpoint endpoint) throws ValidationException { if (DatatypeHelper.isEmpty(endpoint.getLocation())) { throw new ValidationException("Location required"); } } }
&& !DatatypeHelper.isEmpty(endpoint.getResponseLocation())) { urlBuilder = new URLBuilder(endpoint.getResponseLocation()); } else { if (DatatypeHelper.isEmpty(endpoint.getLocation())) { throw new MessageEncodingException("Relying party endpoint location was null or empty."); urlBuilder = new URLBuilder(endpoint.getLocation());
/** {@inheritDoc} */ @SuppressWarnings("unchecked") public Endpoint selectEndpoint() { if(getEntityRoleMetadata() == null){ return null; } List<? extends Endpoint> endpoints = getEntityRoleMetadata().getEndpoints(getEndpointType()); if (endpoints == null || endpoints.size() == 0) { return null; } Endpoint selectedEndpoint; endpoints = filterEndpointsByProtocolBinding(endpoints); if (endpoints == null || endpoints.size() == 0) { return null; } if (endpoints.get(0) instanceof IndexedEndpoint) { selectedEndpoint = selectIndexedEndpoint((List<IndexedEndpoint>) endpoints); } else { selectedEndpoint = selectNonIndexedEndpoint((List<Endpoint>) endpoints); } log.debug("Selected endpoint {} for request", selectedEndpoint.getLocation()); return selectedEndpoint; }
/** * Fills the request with version, issue instants and destination data. * * @param localEntityId entityId of the local party acting as message issuer * @param request request to be filled * @param service service to use as destination for the request */ protected void buildCommonAttributes(String localEntityId, RequestAbstractType request, Endpoint service) { request.setID(generateID()); request.setIssuer(getIssuer(localEntityId)); request.setVersion(SAMLVersion.VERSION_20); request.setIssueInstant(new DateTime()); if (service != null) { // Service is now known when we do not know which IDP will be used request.setDestination(service.getLocation()); } }
/** * Gets the source location used to for the artifacts created by this encoder. * * @param requestContext current request context * * @return source location used to for the artifacts created by this encoder */ protected String getSourceLocation(SAMLMessageContext<RequestAbstractType, Response, NameIdentifier> requestContext) { BasicEndpointSelector selector = new BasicEndpointSelector(); selector.setEndpointType(ArtifactResolutionService.DEFAULT_ELEMENT_NAME); selector.getSupportedIssuerBindings().add(SAMLConstants.SAML1_SOAP11_BINDING_URI); selector.setMetadataProvider(requestContext.getMetadataProvider()); selector.setEntityMetadata(requestContext.getLocalEntityMetadata()); selector.setEntityRoleMetadata(requestContext.getLocalEntityRoleMetadata()); Endpoint acsEndpoint = selector.selectEndpoint(); if (acsEndpoint == null) { log.error("Unable to select source location for artifact. No artifact resolution service defined for issuer."); return null; } return acsEndpoint.getLocation(); } }
URI uri = new URI(context.getPeerEntityEndpoint().getLocation(), true, "UTF-8"); postMethod = new PostMethod(); postMethod.setPath(uri.getPath());