All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.onelogin.saml2.settings.Metadata Maven / Gradle / Ivy
package com.onelogin.saml2.settings;
import java.net.URL;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.xpath.XPathExpressionException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.security.PrivateKey;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import com.onelogin.saml2.model.Contact;
import com.onelogin.saml2.model.Organization;
import com.onelogin.saml2.model.AttributeConsumingService;
import com.onelogin.saml2.model.RequestedAttribute;
import com.onelogin.saml2.util.Constants;
import com.onelogin.saml2.util.Util;
/**
* Metadata class of OneLogin's Java Toolkit.
*
* A class that contains methods related to the metadata of the SP
*/
public class Metadata {
/**
* Private property to construct a logger for this class.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(Metadata.class);
// Constants
private static final int N_DAYS_VALID_UNTIL = 2;
private static final int SECONDS_CACHED = 604800; // 1 week
/**
* AttributeConsumingService
*/
private AttributeConsumingService attributeConsumingService = null;
/**
* Generated metadata in string format
*/
private final String metadataString;
/**
* validUntilTime of the metadata. How long the metadata is valid
*/
private final Calendar validUntilTime;
/**
* cacheDuration of the metadata. Duration of the cache in seconds
*/
private final Integer cacheDuration;
/**
* Constructs the Metadata object.
*
* @param settings
* Saml2Settings object. Setting data
* @param validUntilTime
* Metadata's valid time
* @param cacheDuration
* Duration of the cache in seconds
* @param attributeConsumingService
* AttributeConsumingService of service provider
*
* @throws CertificateEncodingException
*/
public Metadata(Saml2Settings settings, Calendar validUntilTime, Integer cacheDuration, AttributeConsumingService attributeConsumingService) throws CertificateEncodingException {
if (validUntilTime == null) {
this.validUntilTime = Calendar.getInstance();
this.validUntilTime.add(Calendar.DAY_OF_YEAR, N_DAYS_VALID_UNTIL);
} else {
this.validUntilTime = validUntilTime;
}
this.attributeConsumingService = attributeConsumingService;
if (cacheDuration == null) {
this.cacheDuration = SECONDS_CACHED;
} else {
this.cacheDuration = cacheDuration;
}
StrSubstitutor substitutor = generateSubstitutor(settings);
String unsignedMetadataString = substitutor.replace(getMetadataTemplate());
LOGGER.debug("metadata --> " + unsignedMetadataString);
metadataString = unsignedMetadataString;
}
/**
* Constructs the Metadata object.
*
* @param settings
* Saml2Settings object. Setting data
* @param validUntilTime
* Metadata's valid time
* @param cacheDuration
* Duration of the cache in seconds
*
* @throws CertificateEncodingException
*/
public Metadata(Saml2Settings settings, Calendar validUntilTime, Integer cacheDuration) throws CertificateEncodingException {
this(settings, validUntilTime, cacheDuration, null);
}
/**
* Constructs the Metadata object.
*
* @param settings
* Saml2Settings object. Setting data
*
* @throws CertificateEncodingException
*/
public Metadata(Saml2Settings settings) throws CertificateEncodingException {
this(settings, null, null);
}
/**
* Substitutes metadata variables within a string by values.
*
* @param settings
* Saml2Settings object. Setting data
*
* @return the StrSubstitutor object of the metadata
*/
private StrSubstitutor generateSubstitutor(Saml2Settings settings) throws CertificateEncodingException {
Map valueMap = new HashMap();
Boolean wantsEncrypted = settings.getWantAssertionsEncrypted() || settings.getWantNameIdEncrypted();
valueMap.put("id", Util.generateUniqueID(settings.getUniqueIDPrefix()));
valueMap.put("validUntilTime", Util.formatDateTime(validUntilTime.getTimeInMillis()));
valueMap.put("cacheDuration", String.valueOf(cacheDuration));
valueMap.put("spEntityId", settings.getSpEntityId());
valueMap.put("strAuthnsign", String.valueOf(settings.getAuthnRequestsSigned()));
valueMap.put("strWsign", String.valueOf(settings.getWantAssertionsSigned()));
valueMap.put("spNameIDFormat", settings.getSpNameIDFormat());
valueMap.put("spAssertionConsumerServiceBinding", settings.getSpAssertionConsumerServiceBinding());
valueMap.put("spAssertionConsumerServiceUrl", settings.getSpAssertionConsumerServiceUrl().toString());
valueMap.put("sls", toSLSXml(settings.getSpSingleLogoutServiceUrl(), settings.getSpSingleLogoutServiceBinding()));
valueMap.put("strAttributeConsumingService", getAttributeConsumingServiceXml());
valueMap.put("strKeyDescriptor", toX509KeyDescriptorsXML(settings.getSPcert(), wantsEncrypted));
valueMap.put("strContacts", toContactsXml(settings.getContacts()));
valueMap.put("strOrganization", toOrganizationXml(settings.getOrganization()));
return new StrSubstitutor(valueMap);
}
/**
* @return the metadata's template
*/
private static StringBuilder getMetadataTemplate() {
StringBuilder template = new StringBuilder();
template.append("");
template.append("");
template.append("");
template.append("${strKeyDescriptor}");
template.append("${sls}${spNameIDFormat} ");
template.append("");
template.append("${strAttributeConsumingService}");
template.append(" ${strOrganization}${strContacts}");
template.append(" ");
return template;
}
/**
* Generates the AttributeConsumingService section of the metadata's template
*
*
* @return the AttributeConsumingService section of the metadata's template
*/
private String getAttributeConsumingServiceXml() {
StringBuilder attributeConsumingServiceXML = new StringBuilder();
if (attributeConsumingService != null) {
String serviceName = attributeConsumingService.getServiceName();
String serviceDescription = attributeConsumingService.getServiceDescription();
List requestedAttributes = attributeConsumingService.getRequestedAttributes();
attributeConsumingServiceXML.append("");
if (serviceName != null && !serviceName.isEmpty()) {
attributeConsumingServiceXML.append("" + serviceName + " ");
}
if (serviceDescription != null && !serviceDescription.isEmpty()) {
attributeConsumingServiceXML.append("" + serviceDescription + " ");
}
if (requestedAttributes != null && !requestedAttributes.isEmpty()) {
for (RequestedAttribute requestedAttribute : requestedAttributes) {
String name = requestedAttribute.getName();
String friendlyName = requestedAttribute.getFriendlyName();
String nameFormat = requestedAttribute.getNameFormat();
Boolean isRequired = requestedAttribute.isRequired();
List attrValues = requestedAttribute.getAttributeValues() ;
String contentStr = "";
for (String attrValue : attrValues) {
contentStr += "" + attrValue + " ";
}
attributeConsumingServiceXML.append(contentStr + " ");
} else {
attributeConsumingServiceXML.append(contentStr + " />");
}
}
}
attributeConsumingServiceXML.append(" ");
}
return attributeConsumingServiceXML.toString();
}
/**
* Generates the contact section of the metadata's template
*
* @param contacts
* List of contact objects
*
* @return the contact section of the metadata's template
*/
private String toContactsXml(List contacts) {
StringBuilder contactsXml = new StringBuilder();
for (Contact contact : contacts) {
contactsXml.append("");
contactsXml.append("" + contact.getGivenName() + " ");
contactsXml.append("" + contact.getEmailAddress() + " ");
contactsXml.append(" ");
}
return contactsXml.toString();
}
/**
* Generates the organization section of the metadata's template
*
* @param organization
* organization object
* @return the organization section of the metadata's template
*/
private String toOrganizationXml(Organization organization) {
String orgXml = "";
if (organization != null) {
String lang = organization.getOrgLangAttribute();
orgXml = "" + organization.getOrgName()
+ " "
+ organization.getOrgDisplayName() + " " + organization.getOrgUrl() + " ";
}
return orgXml;
}
/**
* Generates the KeyDescriptor section of the metadata's template
*
* @param cert
* the public cert that will be used by the SP to sign and encrypt
* @param wantsEncrypted
* Whether to include the KeyDescriptor for encryption
*
* @return the KeyDescriptor section of the metadata's template
*/
private String toX509KeyDescriptorsXML(X509Certificate cert, Boolean wantsEncrypted) throws CertificateEncodingException {
StringBuilder keyDescriptorXml = new StringBuilder();
if (cert != null) {
Base64 encoder = new Base64(64);
byte[] encodedCert = cert.getEncoded();
String certString = new String(encoder.encode(encodedCert));
keyDescriptorXml.append("");
keyDescriptorXml.append("");
keyDescriptorXml.append("");
keyDescriptorXml.append(""+certString+" ");
keyDescriptorXml.append(" ");
keyDescriptorXml.append(" ");
keyDescriptorXml.append(" ");
if (wantsEncrypted) {
keyDescriptorXml.append("");
keyDescriptorXml.append("");
keyDescriptorXml.append("");
keyDescriptorXml.append(""+certString+" ");
keyDescriptorXml.append(" ");
keyDescriptorXml.append(" ");
keyDescriptorXml.append(" ");
}
}
return keyDescriptorXml.toString();
}
/**
* Generates the KeyDescriptor section of the metadata's template
*
* @param cert
* the public cert that will be used by the SP to sign and encrypt
*
* @return the KeyDescriptor section of the metadata's template
*/
private String toX509KeyDescriptorsXML(X509Certificate cert) throws CertificateEncodingException {
return toX509KeyDescriptorsXML(cert, true);
}
/**
* @return the md:SingleLogoutService section of the metadata's template
*/
private String toSLSXml(URL spSingleLogoutServiceUrl, String spSingleLogoutServiceBinding) {
StringBuilder slsXml = new StringBuilder();
if (spSingleLogoutServiceUrl != null) {
slsXml.append("");
}
return slsXml.toString();
}
/**
* @return the metadata
*/
public final String getMetadataString() {
return metadataString;
}
/**
* Signs the metadata with the key/cert provided
*
* @param metadata
* SAML Metadata XML
* @param key
* Private Key
* @param cert
* x509 Public certificate
* @param signAlgorithm
* Signature Algorithm
*
* @return string Signed Metadata
* @throws XMLSecurityException
* @throws XPathExpressionException
*/
public static String signMetadata(String metadata, PrivateKey key, X509Certificate cert, String signAlgorithm) throws XPathExpressionException, XMLSecurityException
{
return signMetadata(metadata, key, cert, signAlgorithm, Constants.SHA1);
}
/**
* Signs the metadata with the key/cert provided
*
* @param metadata
* SAML Metadata XML
* @param key
* Private Key
* @param cert
* x509 Public certificate
* @param signAlgorithm
* Signature Algorithm
* @param digestAlgorithm
* Digest Algorithm
*
* @return string Signed Metadata
* @throws XMLSecurityException
* @throws XPathExpressionException
*/
public static String signMetadata(String metadata, PrivateKey key, X509Certificate cert, String signAlgorithm, String digestAlgorithm) throws XPathExpressionException, XMLSecurityException
{
Document metadataDoc = Util.loadXML(metadata);
String signedMetadata = Util.addSign(metadataDoc, key, cert, signAlgorithm, digestAlgorithm);
LOGGER.debug("Signed metadata --> " + signedMetadata);
return signedMetadata;
}
}