private void writeSAMLMetadata()

in plugins/core/src/main/java/org/apache/cxf/fediz/core/metadata/MetadataWriter.java [217:314]


    private void writeSAMLMetadata(
        XMLStreamWriter writer,
        HttpServletRequest request,
        FedizContext config,
        String serviceURL
    ) throws Exception {

        SAMLProtocol protocol = (SAMLProtocol)config.getProtocol();

        writer.writeStartElement("md", "SPSSODescriptor", SAML2_METADATA_NS);
        writer.writeAttribute("AuthnRequestsSigned", Boolean.toString(protocol.isSignRequest()));
        writer.writeAttribute("WantAssertionsSigned", "true");
        writer.writeAttribute("protocolSupportEnumeration", "urn:oasis:names:tc:SAML:2.0:protocol");

        if (config.getLogoutURL() != null) {
            writer.writeStartElement("md", "SingleLogoutService", SAML2_METADATA_NS);

            String logoutURL = config.getLogoutURL();
            if (logoutURL.startsWith("/")) {
                logoutURL = StringUtils.extractFullContextPath(request).concat(logoutURL.substring(1));
            } else {
                logoutURL = StringUtils.extractFullContextPath(request).concat(logoutURL);
            }
            writer.writeAttribute("Location", logoutURL);

            writer.writeAttribute("Binding", "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
            writer.writeEndElement(); // SingleLogoutService
        }

        writer.writeStartElement("md", "AssertionConsumerService", SAML2_METADATA_NS);
        writer.writeAttribute("Location", serviceURL);
        writer.writeAttribute("index", "0");
        writer.writeAttribute("isDefault", "true");
        writer.writeAttribute("Binding", "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
        writer.writeEndElement(); // AssertionConsumerService

        if (protocol.getClaimTypesRequested() != null && !protocol.getClaimTypesRequested().isEmpty()) {
            writer.writeStartElement("md", "AttributeConsumingService", SAML2_METADATA_NS);
            writer.writeAttribute("index", "0");

            writer.writeStartElement("md", "ServiceName", SAML2_METADATA_NS);
            writer.writeAttribute("xml:lang", "en");
            writer.writeCharacters(config.getName());
            writer.writeEndElement(); // ServiceName

            for (Claim claim : protocol.getClaimTypesRequested()) {
                writer.writeStartElement("md", "RequestedAttribute", SAML2_METADATA_NS);
                writer.writeAttribute("isRequired", Boolean.toString(claim.isOptional()));
                writer.writeAttribute("Name", claim.getType());
                writer.writeAttribute("NameFormat",
                                      "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified");
                writer.writeEndElement(); // RequestedAttribute
            }

            writer.writeEndElement(); // AttributeConsumingService
        }

        boolean hasSigningKey = false;
        try {
            if (config.getSigningKey().getCrypto() != null) {
                hasSigningKey = true;
            }
        } catch (Exception ex) {
            LOG.info("No signingKey element found in config: " + ex.getMessage());
        }
        if (protocol.isSignRequest() && hasSigningKey) {
            writer.writeStartElement("md", "KeyDescriptor", SAML2_METADATA_NS);
            writer.writeAttribute("use", "signing");

            writer.writeStartElement("ds", "KeyInfo", "http://www.w3.org/2000/09/xmldsig#");
            writer.writeNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
            writer.writeStartElement("ds", "X509Data", "http://www.w3.org/2000/09/xmldsig#");
            writer.writeStartElement("ds", "X509Certificate", "http://www.w3.org/2000/09/xmldsig#");

            // Write the Base-64 encoded certificate
            String keyAlias = config.getSigningKey().getKeyAlias();
            if (keyAlias == null || "".equals(keyAlias)) {
                keyAlias = config.getSigningKey().getCrypto().getDefaultX509Identifier();
            }
            X509Certificate cert =
                CertsUtils.getX509CertificateFromCrypto(config.getSigningKey().getCrypto(), keyAlias);
            if (cert == null) {
                throw new ProcessingException(
                    "No signing certs were found to insert into the metadata using name: "
                        + keyAlias);
            }
            byte[] data = cert.getEncoded();
            String encodedCertificate = Base64.getEncoder().encodeToString(data);
            writer.writeCharacters(encodedCertificate);

            writer.writeEndElement(); // X509Certificate
            writer.writeEndElement(); // X509Data
            writer.writeEndElement(); // KeyInfo
            writer.writeEndElement(); // KeyDescriptor
        }

        writer.writeEndElement(); // SPSSODescriptor
    }