/** * Builds an IdP List out of the idpEntityNames * * @param idpEntityNames The IdPs Entity IDs to include in the IdP List, no list is created when * null * @param serviceURI The binding service for an IdP for a specific binding. Should be null if * there is more than one IdP in the list or if the destination IdP is not known in advance. * @return an IdP List or null when idpEntityNames is null */ protected IDPList buildIDPList(Set<String> idpEntityNames, SingleSignOnService serviceURI) { if (idpEntityNames == null) { return null; } SAMLObjectBuilder<IDPEntry> idpEntryBuilder = (SAMLObjectBuilder<IDPEntry>) builderFactory.getBuilder(IDPEntry.DEFAULT_ELEMENT_NAME); SAMLObjectBuilder<IDPList> idpListBuilder = (SAMLObjectBuilder<IDPList>) builderFactory.getBuilder(IDPList.DEFAULT_ELEMENT_NAME); IDPList idpList = idpListBuilder.buildObject(); for (String entityID : idpEntityNames) { IDPEntry idpEntry = idpEntryBuilder.buildObject(); idpEntry.setProviderID(entityID); idpList.getIDPEntrys().add(idpEntry); // The service URI would be null if the SP does not know in advance // to which IdP the request is sent to. if (serviceURI != null) { idpEntry.setLoc(serviceURI.getLocation()); } } return idpList; }
protected void sendLogoutResponse(Status status, SAMLMessageContext context) throws MetadataProviderException, SAMLException, MessageEncodingException { SAMLObjectBuilder<LogoutResponse> responseBuilder = (SAMLObjectBuilder<LogoutResponse>) builderFactory.getBuilder(LogoutResponse.DEFAULT_ELEMENT_NAME); LogoutResponse logoutResponse = responseBuilder.buildObject(); IDPSSODescriptor idpDescriptor = SAMLUtil.getIDPDescriptor(metadata, context.getPeerEntityId()); SPSSODescriptor spDescriptor = (SPSSODescriptor) context.getLocalEntityRoleMetadata(); String binding = SAMLUtil.getLogoutBinding(idpDescriptor, spDescriptor); SingleLogoutService logoutService = SAMLUtil.getLogoutServiceForBinding(idpDescriptor, binding); logoutResponse.setID(generateID()); logoutResponse.setIssuer(getIssuer(context.getLocalEntityId())); logoutResponse.setVersion(SAMLVersion.VERSION_20); logoutResponse.setIssueInstant(new DateTime()); logoutResponse.setInResponseTo(context.getInboundSAMLMessageId()); logoutResponse.setDestination(logoutService.getLocation()); logoutResponse.setStatus(status); context.setCommunicationProfileId(getProfileIdentifier()); context.setOutboundMessage(logoutResponse); context.setOutboundSAMLMessage(logoutResponse); context.setPeerEntityEndpoint(logoutService); context.setPeerEntityId(idpDescriptor.getID()); context.setPeerEntityRoleMetadata(idpDescriptor); boolean signMessage = context.getPeerExtendedMetadata().isRequireLogoutResponseSigned(); sendMessage(context, signMessage); }
/** * Fills the request with required AuthNContext according to selected options. * * @param request request to fill * @param options options driving generation of the element */ protected void buildAuthnContext(AuthnRequest request, WebSSOProfileOptions options) { Collection<String> contexts = options.getAuthnContexts(); if (contexts != null && contexts.size() > 0) { SAMLObjectBuilder<RequestedAuthnContext> builder = (SAMLObjectBuilder<RequestedAuthnContext>) builderFactory.getBuilder(RequestedAuthnContext.DEFAULT_ELEMENT_NAME); RequestedAuthnContext authnContext = builder.buildObject(); authnContext.setComparison(options.getAuthnContextComparison()); for (String context : contexts) { SAMLObjectBuilder<AuthnContextClassRef> contextRefBuilder = (SAMLObjectBuilder<AuthnContextClassRef>) builderFactory.getBuilder(AuthnContextClassRef.DEFAULT_ELEMENT_NAME); AuthnContextClassRef authnContextClassRef = contextRefBuilder.buildObject(); authnContextClassRef.setAuthnContextClassRef(context); authnContext.getAuthnContextClassRefs().add(authnContextClassRef); } request.setRequestedAuthnContext(authnContext); log.debug("ajoute RequestedAuthnContext=" + request.toString()); } }
/** * Fills the request with required AuthNContext according to selected options. * * @param request request to fill * @param options options driving generation of the element */ protected void builNameIDPolicy(AuthnRequest request, WebSSOProfileOptions options) { if (options.getNameID() != null) { SAMLObjectBuilder<NameIDPolicy> builder = (SAMLObjectBuilder<NameIDPolicy>) builderFactory.getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME); NameIDPolicy nameIDPolicy = builder.buildObject(); nameIDPolicy.setFormat(options.getNameID()); nameIDPolicy.setAllowCreate(options.isAllowCreate()); nameIDPolicy.setSPNameQualifier(getSPNameQualifier()); request.setNameIDPolicy(nameIDPolicy); } }
/** * Fills the request with information about scoping, including IDP in the scope IDP List. * * @param request request to fill * @param serviceURI destination to send the request to * @param options options driving generation of the element, contains list of allowed IDPs */ protected void buildScoping( AuthnRequest request, SingleSignOnService serviceURI, WebSSOProfileOptions options) { if (options.isIncludeScoping() != null && options.isIncludeScoping()) { Set<String> idpEntityNames = options.getAllowedIDPs(); IDPList idpList = buildIDPList(idpEntityNames, serviceURI); SAMLObjectBuilder<Scoping> scopingBuilder = (SAMLObjectBuilder<Scoping>) builderFactory.getBuilder(Scoping.DEFAULT_ELEMENT_NAME); Scoping scoping = scopingBuilder.buildObject(); scoping.setIDPList(idpList); scoping.setProxyCount(options.getProxyCount()); request.setScoping(scoping); } }
/** {@inheritDoc} */ public Attribute encode(BaseAttribute attribute) throws AttributeEncodingException { Attribute samlAttribute = attributeBuilder.buildObject(); samlAttribute.setAttributeName(getAttributeName()); samlAttribute.setAttributeNamespace(getNamespace()); samlAttribute .getAttributeValues() .addAll(encodeAttributeValues(AttributeValue.DEFAULT_ELEMENT_NAME, attribute)); List<XMLObject> attributeValues = samlAttribute.getAttributeValues(); if (attributeValues == null || attributeValues.isEmpty()) { log.debug( "Unable to encode {} attribute. It does not contain any values", attribute.getId()); return null; } return samlAttribute; }
/** * Builds a name ID. The provided value is the textual content of the NameIdentifier. If a {@link * #nameIdQualifier} is not null it is used as the NameIdentifier's name qualifier, otherwise the * attribute issuer's entity id is used. * * @param nameIdValue value of the NameIdentifier * @param resolutionContext current resolution context * @return the constructed NameIdentifier */ protected NameIdentifier buildNameId( String nameIdValue, ShibbolethResolutionContext resolutionContext) { NameIdentifier nameId = nameIdBuilder.buildObject(); nameId.setNameIdentifier(nameIdValue); if (nameIdFormat != null) { nameId.setFormat(nameIdFormat); } if (nameIdQualifier != null) { nameId.setNameQualifier(nameIdQualifier); } else { nameId.setNameQualifier(resolutionContext.getAttributeRequestContext().getLocalEntityId()); } return nameId; }
/** * Returns logout request message ready to be sent to the IDP. * * @param context message context * @param credential information about assertions used to log current user in * @param bindingService service used to deliver the request * @return logoutRequest to be sent to IDP * @throws SAMLException error creating the message * @throws MetadataProviderException error retrieving metadata */ protected LogoutRequest getLogoutRequest( SAMLMessageContext context, SAMLCredential credential, Endpoint bindingService) throws SAMLException, MetadataProviderException { SAMLObjectBuilder<LogoutRequest> builder = (SAMLObjectBuilder<LogoutRequest>) builderFactory.getBuilder(LogoutRequest.DEFAULT_ELEMENT_NAME); LogoutRequest request = builder.buildObject(); buildCommonAttributes(context.getLocalEntityId(), request, bindingService); // Add session indexes SAMLObjectBuilder<SessionIndex> sessionIndexBuilder = (SAMLObjectBuilder<SessionIndex>) builderFactory.getBuilder(SessionIndex.DEFAULT_ELEMENT_NAME); for (AuthnStatement statement : credential.getAuthenticationAssertion().getAuthnStatements()) { SessionIndex index = sessionIndexBuilder.buildObject(); index.setSessionIndex(statement.getSessionIndex()); request.getSessionIndexes().add(index); } if (request.getSessionIndexes().size() == 0) { throw new SAMLException("No session indexes to logout user for were found"); } SAMLObjectBuilder<NameID> nameIDBuilder = (SAMLObjectBuilder<NameID>) builderFactory.getBuilder(NameID.DEFAULT_ELEMENT_NAME); NameID nameID = nameIDBuilder.buildObject(); nameID.setFormat(credential.getNameID().getFormat()); nameID.setNameQualifier(credential.getNameID().getNameQualifier()); nameID.setSPNameQualifier(credential.getNameID().getSPNameQualifier()); nameID.setSPProvidedID(credential.getNameID().getSPProvidedID()); nameID.setValue(credential.getNameID().getValue()); request.setNameID(nameID); return request; }
/** * Returns AuthnRequest SAML message to be used to demand authentication from an IDP described * using idpEntityDescriptor, with an expected response to the assertionConsumer address. * * @param context message context * @param options preferences of message creation * @param assertionConsumer assertion consumer where the IDP should respond * @param bindingService service used to deliver the request * @return authnRequest ready to be sent to IDP * @throws SAMLException error creating the message * @throws MetadataProviderException error retreiving metadata */ protected AuthnRequest getAuthnRequest( SAMLMessageContext context, WebSSOProfileOptions options, AssertionConsumerService assertionConsumer, SingleSignOnService bindingService) throws SAMLException, MetadataProviderException { SAMLObjectBuilder<AuthnRequest> builder = (SAMLObjectBuilder<AuthnRequest>) builderFactory.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME); AuthnRequest request = builder.buildObject(); request.setIsPassive(options.getPassive()); request.setForceAuthn(options.getForceAuthN()); request.setProviderName(options.getProviderName()); request.setVersion(SAMLVersion.VERSION_20); if (options.getIncludeEidas()) { // ne sert à rien // request.setAssertionConsumerServiceURL(options.getIssuer()); // IssuerBuilder issuerBuilder = new IssuerBuilder(); // Issuer issuer = issuerBuilder.buildObject(); // issuer.setFormat(NAME_ISSUER_FORMAT_EIDAS); // log.debug("issuer="+options.getIssuer()); // issuer.setValue(options.getIssuer()); // request.setIssuer(issuer); NameIDPolicy nameIDPolicy = new NameIDPolicyBuilder().buildObject(); nameIDPolicy.setFormat(NAME_POLICY_FORMAT_EIDAS); nameIDPolicy.setAllowCreate(true); request.setNameIDPolicy(nameIDPolicy); QName eidas = new QName("xmlns:eidas", "http://eidas.europa.eu/saml-extensions"); request.getNamespaceManager().registerAttributeName(eidas); Extensions extEidas = new ExtensionsBuilder() .buildObject("urn:oasis:names:tc:SAML:2.0:protocol", "Extensions", "saml2p"); // Extensions extEidas = new EidasExtensions(); Collection<String> colAttr = options.getEidasAttributes(); // XSAnyBuilder raBuild = new XSAnyBuilder(); // <eidas:SPType>public</eidas:SPType> SPType pub = new SPTypeBuilder() .buildObject("http://eidas.europa.eu/saml-extensions", "SPType", "eidas"); // pub.setTextContent(EIDAS_PUBLIC); pub.setSPType(EIDAS_PUBLIC); // XSAny attrs = new XSAnyBuilder().buildObject("http://eidas.europa.eu/saml-extensions", // "RequestedAttributes", "eidas"); extEidas.getUnknownXMLObjects().add(pub); // XSAnyBuilder anyBuilder = (XSAnyBuilder) // Configuration.getBuilderFactory().getBuilder(XSAny.TYPE_NAME); String resAttrs = "<eidas:RequestedAttributes xmlns:eidas=\"http://eidas.europa.eu/saml-extensions\">"; for (String attr : colAttr) { resAttrs += oneAttribute(attr); } resAttrs += "</eidas:RequestedAttributes>"; log.debug("resAttrs=" + resAttrs); EidasExtensionConfiguration eidasExt = new EidasExtensionConfiguration(); eidasExt.configureExtension(); SAMLSchemaBuilder.addExtensionSchema("/schema/saml_eidas_extension.xsd"); BasicParserPool ppMgr = new BasicParserPool(); ppMgr.setNamespaceAware(true); try { ppMgr.setSchema(SAMLSchemaBuilder.getSAML11Schema()); } catch (SAXException ex) { log.error("Erreur schema=" + ex); return null; } InputStream is = new ByteArrayInputStream(resAttrs.getBytes()); Document domAttrsRaq = null; try { domAttrsRaq = ppMgr.parse(is); } catch (XMLParserException e) { log.error("Erreur dom=" + e); return null; } if (domAttrsRaq == null) { log.error("Erreur dom vide"); return null; } RequestedAttributesUnmarshaller unMars = new RequestedAttributesUnmarshaller(); XMLObject attrs = null; try { attrs = unMars.unmarshall(domAttrsRaq.getDocumentElement()); } catch (UnmarshallingException e) { System.err.println("Erreur unMarsh error=" + e); } extEidas.getUnknownXMLObjects().add(attrs); request.setExtensions(extEidas); } buildCommonAttributes(context.getLocalEntityId(), request, bindingService); buildScoping(request, bindingService, options); builNameIDPolicy(request, options); buildAuthnContext(request, options); buildReturnAddress(request, assertionConsumer); return request; }