Skip to content

Commit

Permalink
Merge pull request #178 from WrenSecurity/fix-saml-extension-serializ…
Browse files Browse the repository at this point in the history
…ation

Fix serialization of SAML extensions
  • Loading branch information
pavelhoral authored Sep 27, 2024
2 parents 27e74ad + 1b7656a commit a3a2504
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* $Id: SAML2MetaUtils.java,v 1.9 2009/09/21 17:28:12 exu Exp $
*
* Portions Copyrighted 2010-2015 ForgeRock AS.
* Portions Copyrighted 2024 Wren Security.
*/
package com.sun.identity.saml2.meta;

Expand Down Expand Up @@ -81,14 +82,12 @@ public final class SAML2MetaUtils {
"com.sun.identity.saml2.jaxb.xmlsig:" +
"com.sun.identity.saml2.jaxb.assertion:" +
"com.sun.identity.saml2.jaxb.metadata:" +
"com.sun.identity.saml2.jaxb.metadataattr:" +
"com.sun.identity.saml2.jaxb.metadataattr:" +
"com.sun.identity.saml2.jaxb.entityconfig:" +
"com.sun.identity.saml2.jaxb.schema";
private static final String JAXB_PACKAGE_LIST_PROP =
"com.sun.identity.liberty.ws.jaxb.packageList";
private static JAXBContext jaxbContext = null;
private static final String PROP_JAXB_FORMATTED_OUTPUT =
"jaxb.formatted.output";
private static final String PROP_NAMESPACE_PREFIX_MAPPER =
"com.sun.xml.bind.namespacePrefixMapper";

Expand Down Expand Up @@ -171,18 +170,31 @@ public static Object convertNodeToJAXB(Node node)
return u.unmarshal(node);
}

/**
* See {@link #convertJAXBToString(Object, boolean)}.
*/
public static String convertJAXBToString(Object jaxbObj) throws JAXBException {
return convertJAXBToString(jaxbObj, true, false);
}

/**
* Converts a JAXB object to a <code>String</code> object.
* @param jaxbObj a JAXB object
* @param format flag indicating whether the output XML should be formatted.
* @param fragment flag indicating whether the specified JAXB object is the fragment.
* @return a <code>String</code> representing the JAXB object.
* @exception JAXBException if an error occurs while converting JAXB object
*/
public static String convertJAXBToString(Object jaxbObj)
throws JAXBException {

public static String convertJAXBToString(Object jaxbObj, boolean format, boolean fragment) throws JAXBException {
StringWriter sw = new StringWriter();
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(PROP_JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
if (format) {
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
}
if (fragment) {
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE);
}
marshaller.setProperty(PROP_NAMESPACE_PREFIX_MAPPER, nsPrefixMapper);
marshaller.marshal(jaxbObj, sw);
return sw.toString();
Expand All @@ -194,12 +206,9 @@ public static String convertJAXBToString(Object jaxbObj)
* @param os an <code>OutputStream</code> object
* @exception JAXBException if an error occurs while converting JAXB object
*/
public static void convertJAXBToOutputStream(Object jaxbObj,
OutputStream os)
throws JAXBException {

public static void convertJAXBToOutputStream(Object jaxbObj, OutputStream os) throws JAXBException {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(PROP_JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(PROP_NAMESPACE_PREFIX_MAPPER, nsPrefixMapper);
marshaller.marshal(jaxbObj, os);
}
Expand Down Expand Up @@ -573,36 +582,32 @@ public static IDPSSOConfigElement getIDPSSOConfig(
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);
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;
}
String xmlstr = null;
if (descriptor == null) {
return null;
}

if (sign) {
Document doc = SAML2MetaSecurityUtils.sign(realm, descriptor);
if (doc != 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 = convertJAXBToString(descriptor);
xmlstr = SAML2MetaSecurityUtils.formatBase64BinaryElement(xmlstr);
}
xmlstr = workaroundAbstractRoleDescriptor(xmlstr);
return xmlstr;
} catch (JAXBException e) {
} catch (JAXBException e) {
throw new SAML2MetaException(e.getMessage());
}
}
}

/**
Expand Down Expand Up @@ -734,7 +739,7 @@ private static String importSAML2Entity(SAML2MetaManager metaManager, String rea

return result;
}

private static Object workaroundJAXBBug(Object obj) throws JAXBException {

String metadata = convertJAXBToString(obj);
Expand Down Expand Up @@ -787,28 +792,28 @@ private static void workaroundAbstractRoleDescriptor(Document doc) {
}

private static String workaroundAbstractRoleDescriptor(String xmlstr) {
int index =
xmlstr.indexOf(":" +SAML2MetaConstants.ATTRIBUTE_QUERY_DESCRIPTOR);
if (index == -1) {
return 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;
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@
* $Id: Extensions.java,v 1.2 2008/06/25 05:47:56 qcheng Exp $
*
* Portions Copyrighted 2016 ForgeRock AS.
* Portions Copyrighted 2024 Wren Security.
*/


package com.sun.identity.saml2.protocol;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.sun.identity.saml2.common.SAML2Exception;
import com.sun.identity.saml2.protocol.impl.ExtensionsImpl;
import java.util.List;

/**
/**
* The interface <code>Extensions</code> defines methods for
* adding protcol message extension elements.
*
Expand All @@ -45,33 +45,33 @@
@JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.CLASS,
defaultImpl = ExtensionsImpl.class)
public interface Extensions {
/**

/**
* Sets the <code>Extensions</code> object.
*
* @param value List of Document Elements <code>Extensions</code> objects
* @throws SAML2Exception if the object is immutable.
* @see #getAny
*/
public void setAny(List value) throws SAML2Exception;
/**
public void setAny(List<Object> value) throws SAML2Exception;

/**
* Returns the list of <code>Extensions</code> object.
*
* @return a List of Document Elements <code>Extensions</code> objects.
* @see #setAny(List)
*/
public List getAny() ;
/**
public List<Object> getAny() ;

/**
* Returns a String representation of this object.
*
* @return a String representation of this object.
* @throws SAML2Exception if cannot convert to String.
*/
public String toXMLString() throws SAML2Exception;
/**

/**
* Returns a String representation of this object.
*
* @param includeNSPrefix determines whether or not the namespace
Expand All @@ -81,17 +81,17 @@ public interface Extensions {
* @return the String representation of this Object.
* @throws SAML2Exception if cannot convert to String.
**/

public String toXMLString(boolean includeNSPrefix,
boolean declareNS) throws SAML2Exception;
/**
* Makes this object immutable.

/**
* Makes this object immutable.
*
*/
public void makeImmutable() ;
/**

/**
* Returns value true if object is mutable.
*
* @return true if object is mutable.
Expand Down
Loading

0 comments on commit a3a2504

Please sign in to comment.