list = config.getAttribute();
for (AttributeType avp : list) {
attrMap.put(avp.getName(), avp.getValue());
}
return attrMap;
}
/**
* Returns the realm by parsing the metaAlias. MetaAlias format is
*
* <realm>/<any string without '/'> for non-root realm or
* /<any string without '/'> for root realm.
*
* @param metaAlias The metaAlias.
* @return the realm associated with the metaAlias.
*/
public static String getRealmByMetaAlias(String metaAlias) {
if (metaAlias == null) {
return null;
}
int index = metaAlias.lastIndexOf("/");
if (index == -1 || index == 0) {
return "/";
}
return metaAlias.substring(0, index);
}
/**
* Returns metaAlias embedded in uri.
* @param uri The uri string.
* @return the metaAlias embedded in uri or null if not found.
*/
public static String getMetaAliasByUri(String uri) {
if (uri == null) {
return null;
}
final int index = uri.indexOf(SAML2MetaManager.NAME_META_ALIAS_IN_URI);
final int marker = index + SAML2MetaManager.NAME_META_ALIAS_IN_URI.length();
if (index == -1 || marker == uri.length()) {
return null;
}
return uri.substring(marker);
}
/**
* Returns first policy decision point descriptor in an entity descriptor.
*
* @param eDescriptor The entity descriptor.
* @return policy decision point descriptor or null if it is not found.
*/
public static XACMLPDPDescriptorElement getPolicyDecisionPointDescriptor(
EntityDescriptorElement eDescriptor)
{
XACMLPDPDescriptorElement descriptor = null;
if (eDescriptor != null) {
List list =
eDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
for (Iterator i = list.iterator();
i.hasNext() && (descriptor == null);
) {
Object obj = i.next();
if (obj instanceof XACMLPDPDescriptorElement) {
descriptor = (XACMLPDPDescriptorElement)obj;
}
}
}
return descriptor;
}
/**
* Returns first policy enforcement point descriptor in an entity
* descriptor.
*
* @param eDescriptor The entity descriptor.
* @return policy enforcement point descriptor or null if it is not found.
*/
public static XACMLAuthzDecisionQueryDescriptorElement
getPolicyEnforcementPointDescriptor(
EntityDescriptorElement eDescriptor)
{
XACMLAuthzDecisionQueryDescriptorElement descriptor = null;
if (eDescriptor != null) {
List list =
eDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
for (Iterator i = list.iterator();
i.hasNext() && (descriptor == null);
) {
Object obj = i.next();
if (obj instanceof XACMLAuthzDecisionQueryDescriptorElement) {
descriptor = (XACMLAuthzDecisionQueryDescriptorElement)obj;
}
}
}
return descriptor;
}
/**
* Returns first service provider's SSO descriptor in an entity
* descriptor.
* @param eDescriptor The entity descriptor.
* @return SPSSODescriptorElement
for the entity or null if
* not found.
*/
public static SPSSODescriptorElement getSPSSODescriptor(
EntityDescriptorElement eDescriptor)
{
if (eDescriptor == null) {
return null;
}
List list =
eDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
for(Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
// TODO: may need to cache to avoid using instanceof
if (obj instanceof SPSSODescriptorElement) {
return (SPSSODescriptorElement)obj;
}
}
return null;
}
/**
* Returns first identity provider's SSO descriptor in an entity
* descriptor.
* @param eDescriptor The entity descriptor.
* @return IDPSSODescriptorElement
for the entity or null if
* not found.
*/
public static IDPSSODescriptorElement getIDPSSODescriptor(
EntityDescriptorElement eDescriptor)
{
if (eDescriptor == null) {
return null;
}
List list =
eDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
for(Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof IDPSSODescriptorElement) {
return (IDPSSODescriptorElement)obj;
}
}
return null;
}
/**
* Returns attribute authority descriptor in an entity descriptor.
*
* @param eDescriptor The entity descriptor.
* @return an AttributeAuthorityDescriptorElement
object for
* the entity or null if not found.
*/
public static AttributeAuthorityDescriptorElement
getAttributeAuthorityDescriptor(EntityDescriptorElement eDescriptor)
{
if (eDescriptor == null) {
return null;
}
List list =
eDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
for(Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof AttributeAuthorityDescriptorElement) {
return (AttributeAuthorityDescriptorElement)obj;
}
}
return null;
}
/**
* Returns attribute query descriptor in an entity descriptor.
*
* @param eDescriptor The entity descriptor.
* @return an AttributeQueryDescriptorElement
object for
* the entity or null if not found.
*/
public static AttributeQueryDescriptorElement
getAttributeQueryDescriptor(EntityDescriptorElement eDescriptor)
{
if (eDescriptor == null) {
return null;
}
List list =
eDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
for(Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof AttributeQueryDescriptorElement) {
return (AttributeQueryDescriptorElement)obj;
}
}
return null;
}
/**
* Returns authentication authority descriptor in an entity descriptor.
*
* @param eDescriptor The entity descriptor.
* @return an AuthnAuthorityDescriptorElement
object for
* the entity or null if not found.
*/
public static AuthnAuthorityDescriptorElement
getAuthnAuthorityDescriptor(EntityDescriptorElement eDescriptor)
{
if (eDescriptor == null) {
return null;
}
List list =
eDescriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
for(Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof AuthnAuthorityDescriptorElement) {
return (AuthnAuthorityDescriptorElement)obj;
}
}
return null;
}
/**
* Get the first value of set by given key searching in the given map.
* return null if attrMap
is null or key
* is null.
*
* @param attrMap Map of which set is to be added.
* @param key Key of the entry to be added.
* @return the first value of a matching set by the given key.
*/
public static String getFirstEntry(Map attrMap, String key) {
String retValue = null;
if ((attrMap != null) && !attrMap.isEmpty()) {
Set valueSet = (Set)attrMap.get(key);
if ((valueSet != null) && !valueSet.isEmpty()) {
retValue = (String)valueSet.iterator().next();
}
}
return retValue;
}
/**
* Adds a set of a given value to a map. Set will not be added if
* attrMap
is null or value
is null or
* key
is null.
*
* @param attrMap Map of which set is to be added.
* @param key Key of the entry to be added.
* @param value Value to be added to the Set.
*/
public static void fillEntriesInSet(Map attrMap, String key, String value) {
if ((key != null) && (value != null) && (attrMap != null)) {
Set valueSet = new HashSet();
valueSet.add(value);
attrMap.put(key, valueSet);
}
}
/**
* Returns first service provider's SSO configuration in an entity.
* @param eConfig EntityConfigElement
of the entity to
* be retrieved.
* @return SPSSOConfigElement
for the entity or null if not
* found.
* @throws SAML2MetaException if unable to retrieve the first service
* provider's SSO configuration.
*/
public static SPSSOConfigElement getSPSSOConfig(EntityConfigElement eConfig)
throws SAML2MetaException {
if (eConfig == null) {
return null;
}
List list =
eConfig.getIDPSSOConfigOrSPSSOConfigOrAuthnAuthorityConfig();
for(Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof SPSSOConfigElement) {
return (SPSSOConfigElement)obj;
}
}
return null;
}
/**
* Returns first identity provider's SSO configuration in an entity
* @param eConfig EntityConfigElement
of the entity to
* be retrieved.
* @return IDPSSOConfigElement
for the entity or null if not
* found.
* @throws SAML2MetaException if unable to retrieve the first identity
* provider's SSO configuration.
*/
public static IDPSSOConfigElement getIDPSSOConfig(
EntityConfigElement eConfig) throws SAML2MetaException {
if (eConfig == null) {
return null;
}
List list =
eConfig.getIDPSSOConfigOrSPSSOConfigOrAuthnAuthorityConfig();
for(Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof IDPSSOConfigElement) {
return (IDPSSOConfigElement)obj;
}
}
return null;
}
public static String exportStandardMeta(String realm, String entityID,
boolean sign)
throws SAML2MetaException {
try {
SAML2MetaManager metaManager = new SAML2MetaManager();
EntityDescriptorElement descriptor =
metaManager.getEntityDescriptor(realm, entityID);
String xmlstr = null;
if (descriptor == null) {
return null;
}
if (sign) {
Document doc = SAML2MetaSecurityUtils.sign(realm, descriptor);
if (doc != null) {
xmlstr = XMLUtils.print(doc);
}
}
if (xmlstr == null) {
xmlstr = convertJAXBToString(descriptor);
xmlstr = SAML2MetaSecurityUtils.formatBase64BinaryElement(
xmlstr);
}
xmlstr = workaroundAbstractRoleDescriptor(xmlstr);
return xmlstr;
} catch (JAXBException e) {
throw new SAML2MetaException(e.getMessage());
}
}
/**
*
* @param metadata A string representing an EntityDescriptorElement XML document
* @return EntityDescriptorElement an EntityDescriptorElement from the passed metadata
* @throws SAML2MetaException If there was a problem with the parsed metadata
* @throws JAXBException If there was a problem parsing the metadata
*/
public static EntityDescriptorElement getEntityDescriptorElement(String metadata)
throws SAML2MetaException, JAXBException {
Document doc = XMLUtils.toDOMDocument(metadata, debug);
if (doc == null) {
throw new SAML2MetaException("Null document");
}
Element docElem = doc.getDocumentElement();
if ((!SAML2MetaConstants.ENTITY_DESCRIPTOR.equals(docElem.getLocalName())) ||
(!SAML2MetaConstants.NS_METADATA.equals(docElem.getNamespaceURI()))) {
throw new SAML2MetaException("Invalid descriptor");
}
Object element = preProcessSAML2Document(doc);
return (element instanceof EntityDescriptorElement) ?
(EntityDescriptorElement)element : null;
}
/**
* For the given XML metadata document representing either a SAML2 EntityDescriptorElement or EntitiesDescriptorElement,
* return a list of entityId's for all the Entities created. Carries out a signature validation of the document as
* part of the import process.
* @param metaManager An instance of the SAML2MetaManager, used to do the actual create.
* @param realm The realm to create the Entities in
* @param doc The XML document that represents either an EntityDescriptorElement or EntitiesDescriptorElement
* @return A list of all entityId's imported or an empty list if no Entities were imported.
* @throws SAML2MetaException for any issues as a result of trying to create the Entities.
* @throws JAXBException for any issues converting the document into a JAXB document.
*/
public static List importSAML2Document(SAML2MetaManager metaManager,
String realm, Document doc) throws SAML2MetaException, JAXBException {
List result = new ArrayList(1);
Object element = preProcessSAML2Document(doc);
if (element instanceof EntityDescriptorElement) {
String entityId = importSAML2Entity(metaManager, realm,
(EntityDescriptorElement)element);
if (entityId != null) {
result.add(entityId);
}
} else if (element instanceof EntitiesDescriptorElement) {
result = importSAML2Entites(metaManager, realm,
(EntitiesDescriptorElement)element);
}
if (debug.messageEnabled()) {
debug.message("SAML2MetaUtils.importSAML2Document: " +
"Created " + result + " entities");
}
return result;
}
private static Object preProcessSAML2Document(Document doc) throws SAML2MetaException, JAXBException {
SAML2MetaSecurityUtils.verifySignature(doc);
workaroundAbstractRoleDescriptor(doc);
Object obj = convertNodeToJAXB(doc);
// Remove any Extensions elements as these are currently not supported.
obj = workaroundJAXBBug(obj);
return obj;
}
private static List importSAML2Entites(SAML2MetaManager metaManager, String realm,
EntitiesDescriptorElement descriptor) throws SAML2MetaException {
List result = new ArrayList();
List descriptors = descriptor.getEntityDescriptorOrEntitiesDescriptor();
if (descriptors != null && !descriptors.isEmpty()) {
Iterator entities = descriptors.iterator();
while (entities.hasNext()) {
Object o = entities.next();
if (o instanceof EntityDescriptorElement) {
String entityId = importSAML2Entity(metaManager, realm,
(EntityDescriptorElement) o);
if (entityId != null) {
result.add(entityId);
}
}
}
}
return result;
}
private static String importSAML2Entity(SAML2MetaManager metaManager, String realm,
EntityDescriptorElement descriptor) throws SAML2MetaException {
String result = null;
List roles = descriptor.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
Iterator it = roles.iterator();
while (it.hasNext()) {
RoleDescriptorType role = (RoleDescriptorType)it.next();
List protocols = role.getProtocolSupportEnumeration();
if (!protocols.contains(SAML2Constants.PROTOCOL_NAMESPACE)) {
if (debug.messageEnabled()) {
debug.message("SAML2MetaUtils.importSAML2Entity: "
+ "Removing non-SAML2 role from entity "
+ descriptor.getEntityID());
}
it.remove();
}
}
if (roles.size() > 0) {
metaManager.createEntityDescriptor(realm, descriptor);
result = descriptor.getEntityID();
}
return result;
}
private static Object workaroundJAXBBug(Object obj) throws JAXBException {
String metadata = convertJAXBToString(obj);
String replaced = metadata.replaceAll("<(.*:)?Extensions/>", "");
if (metadata.equalsIgnoreCase(replaced)) {
return obj;
} else {
return convertStringToJAXB(replaced);
}
}
private static void workaroundAbstractRoleDescriptor(Document doc) {
NodeList nl = doc.getDocumentElement().getElementsByTagNameNS(
SAML2MetaConstants.NS_METADATA,SAML2MetaConstants.ROLE_DESCRIPTOR);
int length = nl.getLength();
if (length == 0) {
return;
}
for (int i = 0; i < length; i++) {
Element child = (Element)nl.item(i);
String type = child.getAttributeNS(SAML2Constants.NS_XSI, "type");
if (type != null) {
if ((type.equals(
SAML2MetaConstants.ATTRIBUTE_QUERY_DESCRIPTOR_TYPE)) ||
(type.endsWith(":" +
SAML2MetaConstants.ATTRIBUTE_QUERY_DESCRIPTOR_TYPE))) {
String newTag = type.substring(0, type.length() - 4);
String xmlstr = XMLUtils.print(child);
int index = xmlstr.indexOf(
SAML2MetaConstants.ROLE_DESCRIPTOR);
xmlstr = "<" + newTag + xmlstr.substring(index +
SAML2MetaConstants.ROLE_DESCRIPTOR.length());
if (!xmlstr.endsWith("/>")) {
index = xmlstr.lastIndexOf("");
xmlstr = xmlstr.substring(0, index) + "" + newTag +
">";
}
Document tmpDoc = XMLUtils.toDOMDocument(xmlstr, debug);
Node newChild =
doc.importNode(tmpDoc.getDocumentElement(), true);
child.getParentNode().replaceChild(newChild, child);
}
}
}
}
private static String workaroundAbstractRoleDescriptor(String xmlstr) {
int index =
xmlstr.indexOf(":" +SAML2MetaConstants.ATTRIBUTE_QUERY_DESCRIPTOR);
if (index == -1) {
return xmlstr;
}
int index2 = xmlstr.lastIndexOf("<", index);
if (index2 == -1) {
return xmlstr;
}
String prefix = xmlstr.substring(index2 + 1, index);
String type = prefix + ":" +
SAML2MetaConstants.ATTRIBUTE_QUERY_DESCRIPTOR_TYPE;
xmlstr = xmlstr.replaceAll("<" + prefix + ":" +
SAML2MetaConstants.ATTRIBUTE_QUERY_DESCRIPTOR,
"<" + SAML2MetaConstants.ROLE_DESCRIPTOR + " " +
SAML2Constants.XSI_DECLARE_STR + " xsi:type=\"" + type + "\"");
xmlstr = xmlstr.replaceAll("" + prefix + ":" +
SAML2MetaConstants.ATTRIBUTE_QUERY_DESCRIPTOR,
"" + SAML2MetaConstants.ROLE_DESCRIPTOR);
return xmlstr;
}
}