se.litsec.opensaml.saml2.metadata.MetadataUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opensaml3-ext Show documentation
Show all versions of opensaml3-ext Show documentation
OpenSAML 3.X utility extension library
/*
* The opensaml-ext project is an open-source package that extends OpenSAML
* with useful extensions and utilities.
*
* More details on
* Copyright (C) 2017 Litsec AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package se.litsec.opensaml.saml2.metadata;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.opensaml.core.xml.schema.XSString;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.ext.saml2mdattr.EntityAttributes;
import org.opensaml.saml.ext.saml2mdui.Description;
import org.opensaml.saml.ext.saml2mdui.DisplayName;
import org.opensaml.saml.ext.saml2mdui.UIInfo;
import org.opensaml.saml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml.saml2.metadata.Extensions;
import org.opensaml.saml.saml2.metadata.KeyDescriptor;
import org.opensaml.saml.saml2.metadata.SSODescriptor;
import org.opensaml.security.credential.UsageType;
import org.opensaml.security.x509.BasicX509Credential;
import org.opensaml.security.x509.X509Credential;
import org.opensaml.xmlsec.signature.X509Data;
import se.litsec.opensaml.utils.X509CertificateUtils;
/**
* Utility methods for accessing metadata elements.
*
* @author Martin Lindström ([email protected])
*/
public class MetadataUtils {
/**
* Finds the first extension matching the supplied type.
*
* @param extensions
* the {@link Extensions} to search
* @param clazz
* the extension type
* @param
* the type of the extension
* @return the matching extension
*/
public static Optional getMetadataExtension(Extensions extensions, Class clazz) {
if (extensions == null) {
return Optional.empty();
}
return extensions.getOrderedChildren()
.stream()
.filter(e -> clazz.isAssignableFrom(e.getClass()))
.map(clazz::cast)
.findFirst();
}
/**
* Finds all extensions matching the supplied type.
*
* @param extensions
* the {@link Extensions} to search
* @param clazz
* the extension type
* @param
* the type of the extension
* @return a (possibly empty) list of extensions elements of the given type
*/
public static List getMetadataExtensions(Extensions extensions, Class clazz) {
if (extensions == null) {
return Collections.emptyList();
}
return extensions.getOrderedChildren()
.stream()
.filter(e -> clazz.isAssignableFrom(e.getClass()))
.map(clazz::cast)
.collect(Collectors.toList());
}
/**
* Returns the {@code EntityAttributes} element that is placed as an extension to the supplied entity descriptor.
*
* @param ed
* the entity descriptor
* @return the EntityAttributes element
*/
public static Optional getEntityAttributes(EntityDescriptor ed) {
return getMetadataExtension(ed.getExtensions(), EntityAttributes.class);
}
/**
* Utility method that returns a list of the {@code mdui:DisplayName} element found in the SSO descriptor extension of
* the supplied entity descriptor.
*
* @param ed
* the entity descriptor
* @return a (possibly empty) list of {@code DisplayName} elements
*/
public static List getUiDisplayNames(EntityDescriptor ed) {
SSODescriptor ssoDescriptor = MetadataUtils.getSSODescriptor(ed);
if (ssoDescriptor == null) {
return Collections.emptyList();
}
Optional uiInfo = getMetadataExtension(ssoDescriptor.getExtensions(), UIInfo.class);
return uiInfo.map(UIInfo::getDisplayNames).orElseGet(Collections::emptyList);
}
/**
* Utility method that returns the {@code mdui:DisplayName} element for the given language tag from the SSO descriptor
* extension of the supplied entity descriptor.
*
* @param ed
* the entity descriptor
* @param language
* the language tag
* @return the display name for the given language
*/
public static Optional getUiDisplayName(EntityDescriptor ed, String language) {
return getUiDisplayNames(ed).stream()
.filter(dn -> language.equals(dn.getXMLLang()))
.map(XSString::getValue)
.findFirst();
}
/**
* Utility method that returns a list of the {@code mdui:Description} element found in the SSO descriptor extension of
* the supplied entity descriptor.
*
* @param ed
* the entity descriptor
* @return a (possibly empty) list of {@code Description} elements
*/
public static List getUiDescriptions(EntityDescriptor ed) {
SSODescriptor ssoDescriptor = MetadataUtils.getSSODescriptor(ed);
if (ssoDescriptor == null) {
return Collections.emptyList();
}
Optional uiInfo = getMetadataExtension(ssoDescriptor.getExtensions(), UIInfo.class);
return uiInfo.map(UIInfo::getDescriptions).orElseGet(Collections::emptyList);
}
/**
* Utility method that returns the {@code mdui:Description} element for the given language tag from the SSO descriptor
* extension of the supplied entity descriptor.
*
* @param ed
* the entity descriptor
* @param language
* the language tag
* @return the description for the given language
*/
public static Optional getUiDescription(EntityDescriptor ed, String language) {
return getUiDescriptions(ed).stream()
.filter(dn -> language.equals(dn.getXMLLang()))
.map(XSString::getValue)
.findFirst();
}
/**
* Utility that extracs certificates found under the KeyDescriptor elements of a metadata record.
*
* If {@link UsageType#SIGNING} is supplied, the method will return all certificates with usage type signing, but also
* those that does not have a usage. And the same goes for encryption.
*
*
* @param ed
* the metadata record
* @param usageType
* the requested usage type
* @return a list of credentials
*/
public static List getMetadataCertificates(EntityDescriptor ed, UsageType usageType) {
SSODescriptor descriptor = getSSODescriptor(ed);
if (descriptor == null) {
return Collections.emptyList();
}
List creds = new ArrayList<>();
for (KeyDescriptor kd : descriptor.getKeyDescriptors()) {
if (usageType.equals(kd.getUse()) || kd.getUse() == null || UsageType.UNSPECIFIED.equals(kd.getUse())) {
if (kd.getKeyInfo() == null) {
continue;
}
for (X509Data xd : kd.getKeyInfo().getX509Datas()) {
for (org.opensaml.xmlsec.signature.X509Certificate cert : xd.getX509Certificates()) {
try {
creds.add(new BasicX509Credential(
X509CertificateUtils.decodeCertificate(new ByteArrayInputStream(Base64.getDecoder().decode(cert.getValue())))));
}
catch (Exception e) {
}
}
}
}
}
return creds;
}
/**
* Returns the SSODescriptor for the supplied SP or IdP entity descriptor.
*
* @param ed
* the entity descriptor
* @return the SSODescriptor
*/
private static SSODescriptor getSSODescriptor(EntityDescriptor ed) {
if (ed.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) != null) {
return ed.getIDPSSODescriptor(SAMLConstants.SAML20P_NS);
}
else {
return ed.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
}
}
// Hidden
private MetadataUtils() {
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy