[OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object

2,370 views
Skip to first unread message

Sidhartha Priye

unread,
Feb 26, 2010, 8:31:06 PM2/26/10
to mace-open...@internet2.edu, Sidhartha Priye
Hello everyone!!!

I am injecting a SAML Assertion in a SOAP Header from the SOAPClient and then issuing a service request to a Apache CXF webservice. On the webservice end I have a JAX-WS SOAP Handler that intercepts and unmarshals the header.

However when I am trying to unmarshall the Assertion Element, I am getting this following exception stacktrace:


[2/26/10 17:16:11:596 EST] 0000001c SystemErr    R  java.lang.IllegalArgumentException: local part cannot be "null" when
creating a QName
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
javax.xml.namespace.QName.<init>(Unknown Source)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
javax.xml.namespace.QName.<init>(Unknown Source)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
org.opensaml.xml.util.XMLHelper.constructQName(XMLHelper.java:433)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
org.opensaml.xml.util.XMLHelper.getNodeQName(XMLHelper.java:171)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshallAttribute(AbstractXMLObjectUnmarshaller.java:215)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshall(AbstractXMLObjectUnmarshaller.java:107)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
com.syscom.hsc.web.soap.ServiceSAMLHandler.handleMessage(ServiceSAMLHandler.java:222)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
com.syscom.hsc.web.soap.ServiceSAMLHandler.handleMessage(ServiceSAMLHandler.java:1)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
org.apache.cxf.jaxws.handler.HandlerChainInvoker.invokeHandleMessage(HandlerChainInvoker.java:335)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
****************************************************************************************************************
This is the line of code where the exception is being thrown on the JAX WS Service Handler
***************************************************************************************************************
<code>
            UnmarshallerFactory unmarshallerFactory = Configuration
                  .getUnmarshallerFactory();

            Unmarshaller unmarshaller = unmarshallerFactory
                  .getUnmarshaller(assertionElement);
          
            Assertion samlAssertion =
                (Assertion) unmarshaller.unmarshall(assertionElement);
</code>

This is how I am getting the AssertionElement
<code>
      SOAPHeader sh = smc.getMessage().getSOAPHeader();

            // check for wsse:security element under SOAP Header
            Node wsseElement = sh.getFirstChild();

          // check for SAML assertion under wsse:security
element
            Element assertionElement = (Element)
wsseElement.getFirstChild();

</code>

****************************************************************************************************************
On the client side SAML Handler, I have tried both these approaches
for creating the Assertion object
****************************************************************************************************************
<code>
                    DefaultBootstrap.bootstrap();
                  
                    SOAPMessage message = smc.getMessage();
                    SOAPPart soapPart = message.getSOAPPart();
                    SOAPEnvelope soapEnvelope =
soapPart.getEnvelope();
                    Name wsseHeaderName =
soapEnvelope.createName("Security",
                          "wsse", WS_SECURITY_NS_URI);
                    if (soapEnvelope.getHeader() == null) {
                      soapEnvelope.addHeader();
                    }
                    SOAPHeaderElement securityElement =
soapEnvelope.getHeader()
                          .addHeaderElement(wsseHeaderName);

                    //    APPROACH 1: Get the builder factory
                    SAMLObjectBuilder<Assertion> ab =
(SAMLObjectBuilder<Assertion>)
                                                          
builderFactory.getBuilder(Assertion.DEFAULT_ELEMENT_NAME);

                    // APPROACH 2: Get the builder factory
                    //  AssertionBuilder ab =
(AssertionBuilder)builderFactory.getBuilder(Assertion.DEFAULT_ELEMENT_NAME);
                    Assertion assertion = ab.buildObject();
..............
............
.............

                        try {
                                        assertionElement =
                                              
Configuration.getMarshallerFactory().getMarshaller(assertion).marshall(assertion);
                                } catch (MarshallingException e) {
                                    e.printStackTrace();
                                }
</code>
*****************************************************************************************************************

I have hit a dead end on this critical path of implementing a Spring/SAML/CXF SSO protoype effort currently for a client.
Any help would be greatly appreciated.




Brent Putman

unread,
Mar 1, 2010, 5:18:20 AM3/1/10
to mace-open...@internet2.edu


On 2/26/2010 8:31 PM, Sidhartha Priye wrote:



[2/26/10 17:16:11:596 EST] 0000001c SystemErr    R  java.lang.IllegalArgumentException: local part cannot be "null" when
creating a QName
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
javax.xml.namespace.QName.<init>(Unknown Source)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
javax.xml.namespace.QName.<init>(Unknown Source)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
org.opensaml.xml.util.XMLHelper.constructQName(XMLHelper.java:433)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
org.opensaml.xml.util.XMLHelper.getNodeQName(XMLHelper.java:171)
[2/26/10 17:16:11:612 EST] 0000001c SystemErr    R      at
org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshallAttribute(AbstractXMLObjectUnmarshaller.java:215)



It's failing trying to construct a QName out of an DOM Attr Node.    Either the XML you're sending is malformed in some way, or possibly the way that you parsed the structure into a DOM Element is causing a problem, perhaps it's not namespace-aware or something.  I'd confirm exactly what you are sending from the client by getting a trace of the message, just to be sure.





This is how I am getting the AssertionElement
<code>
      SOAPHeader sh = smc.getMessage().getSOAPHeader();

            // check for wsse:security element under SOAP Header
            Node wsseElement = sh.getFirstChild();

          // check for SAML assertion under wsse:security
element
            Element assertionElement = (Element)
wsseElement.getFirstChild();


Personally, I wouldn't necessarily assume that the first Node under the Security header is your Assertion.  You probably want to specifically check.  Your client might be generating something else in there automatically, like a WSS timestamp or something.  For that matter, it might not even be an Element Node at all, you could have whitespace Text node, etc.  OpenSAML has some helper methods there that you might want to use if you don't want to write your own code for that, like XMLHelper.getChildElementsByTagNameNS(Element root, String namespaceURI, String localName).

--Brent


Sidhartha Priye

unread,
Mar 1, 2010, 9:48:59 AM3/1/10
to mace-open...@internet2.edu
Thanks a bunch Brent,

Here is the XML of the SOAP Header that I am generating.  I am trying to test with a very basic Assertion element.

http://localhost:9088mbrendish


That being said, I have access to the AssertionElement.

UnmarshallerFactory unmarshallerfactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerfactory.getUnmarshaller(samlElem);
     
out.println("Unmarshalling SAML document root element{}"+XMLHelper.getNodeQName(samlElem));

The output is:

[3/1/10 3:02:16:725 EST] 0000001c SystemOut    O  Unmarshalling SAML document root element {}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion

However It fails here
          XMLObject xmlObject = unmarshaller.unmarshall(samlElem);

When it was not obvious, I decompiled the AbstractXMLObjectUnmarshaller, added my own trace.
           
System.out.println("Node name"+attribute.getNodeName());      
System.out.println("Node value"+attribute.getNodeValue());          
System.out.println("Node type"+attribute.getNodeType());
if(attribute.getNodeType() == 2)
                unmarshallAttribute(xmlObject, Attr)attribute);
        }

The output is -
[3/1/10 3:02:16:741 EST] 0000001c SystemOut    O  Node name ID
[3/1/10 3:02:16:741 EST] 0000001c SystemOut    O  Node
value_33776a319493ad607b7ab3e689482e45
[3/1/10 3:02:16:741 EST] 0000001c SystemOut    O  Node type 2

thanks
Sid

________________________________


From: Brent Putman <put...@georgetown.edu>
To: mace-open...@internet2.edu
Sent: Mon, March 1, 2010 5:18:20 AM
Subject: Re: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object

Sidhartha Priye

unread,
Mar 1, 2010, 9:53:48 AM3/1/10
to mace-open...@internet2.edu
Looks like my Assertion XML Sample was stripped out in my last post. Here it is

http://localhost:9088mbrendish

thanks
Sid

Sidhartha Priye

unread,
Mar 1, 2010, 9:55:28 AM3/1/10
to mace-open...@internet2.edu
Here is the Assertion Element that was stripped off from my previous post

http://localhost:9088mbrendish

thanks
Sid

From: Sidhartha Priye <sidhart...@yahoo.com>
To: mace-open...@internet2.edu
Sent: Mon, March 1, 2010 9:48:59 AM

Subject: Re: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object

Sidhartha Priye

unread,
Mar 1, 2010, 10:02:23 AM3/1/10
to mace-open...@internet2.edu
Not sure why my Assertion XML is getting stripped.

Brent - How can I provide the XML. I am taking another shot

<code>

<?xml version="1.0" encoding="UTF-8"?>
http://localhost:9088mbrendishGETFULLEOPINWRK'>http://web.hsc.syscom.com/">GETFULLEOPINWRK-1'>http://web.hsc.syscom.com/">-1

</code>

thanks
Sid
Sent: Mon, March 1, 2010 9:55:28 AM

Subject: Re: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object

Sidhartha Priye

unread,
Mar 1, 2010, 10:57:29 AM3/1/10
to mace-open...@internet2.edu
I think yahoo mail Rich text was the culprit. sending via plain text. Hopefully it will go this time

<soap:Header><wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_33776a319493ad607b7ab3e689482e45"
IssueInstant="2010-03-01T05:30:49.730Z"
Version="2.0"><saml2:Issuer>http://localhost:9088</saml2:Issuer><saml2:Subject><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">mbrendish</saml2:NameID></saml2:Subject></saml2:Assertion></wsse:Security></soap:Header>


thanks
Sid


>
>From: Sidhartha Priye <sidhart...@yahoo.com>
>To: mace-open...@internet2.edu
>Sent: Mon, March 1, 2010 10:02:23 AM
>Subject: Re: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>
>

>Not sure why my Assertion XML is getting stripped.
>
>Brent - How can I provide the XML. I am taking another shot
>
><code>
>
><?xml version="1.0" encoding="UTF-8"?>

>>http://localhost:9088 mbrendish GETFULLEOPINWRK'>http://web.hsc.syscom.com/">GETFULLEOPINWRK -1'>http://web.hsc.syscom.com/">-1

Sidhartha Priye

unread,
Mar 1, 2010, 12:39:13 PM3/1/10
to mace-open...@internet2.edu
Scott, Brent

Essentially here is the code that I have when I am unmarshalling the Assertion Element in the SOAP Header

DefaultBootstrap.bootstrap();
SOAPHeader sh = smc.getMessage().getSOAPHeader();

// check for wsse:security element under SOAP Header
Node wsseElement = sh.getFirstChild();

if (wsseElement == null || !"Security".equals(wsseElement.getLocalName())
|| !WS_SECURITY_URI.equals(wsseElement.getNamespaceURI())) {
throw createSOAPFaultException("Missing or invalid WS-Security Header",
true);


}

// check for SAML assertion under wsse:security element

assertionElement = (Element) wsseElement.getFirstChild();

if (assertionElement == null
|| !"Assertion".equals(assertionElement.getLocalName())
|| !SAMLConstants.SAML20_NS.equals(assertionElement.getNamespaceURI())) {
throw createSOAPFaultException("Missing or invalid SAML Assertion", true);
}

Assertion samlAssertion =
(Assertion) unmarshall(assertionElement);

................................

protected static XMObject unmarshall(Element samlElem) {


UnmarshallerFactory unmarshallerfactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerfactory.getUnmarshaller(samlElem);

try {
XMLObject xmlObject = unmarshaller.unmarshall(samlElem);
out.println("SAML document root element unmarshalled");
return xmlObject;
} catch (UnmarshallingException e) {
out.println("Unable to unmarshall XML DOM"+e);
}
return null;
}

Trace inside the AbstractXMLObjectUnmarshaller.unmarshallAttribute prints this "DatatypeHelper.safeTrimOrNullString(attribute.getNamespaceURI())" to be null. How can I make my code namespace aware, esp when I am parsing from a SOAP Header.

thanks
Sid

----- Original Message ----
> From: Sidhartha Priye <sidhart...@yahoo.com>
> To: mace-open...@internet2.edu
> Sent: Mon, March 1, 2010 10:57:29 AM
> Subject: Re: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

> I think yahoo mail Rich text was the culprit. sending via plain text. Hopefully
> it will go this time
>
>

> xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">


> xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
> ID="_33776a319493ad607b7ab3e689482e45"
> IssueInstant="2010-03-01T05:30:49.730Z"

> Version="2.0">http://localhost:9088


> Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">mbrendish
>
>

> thanks
> Sid
>
>
> >
> >From: Sidhartha Priye
> >To: mace-open...@internet2.edu
> >Sent: Mon, March 1, 2010 10:02:23 AM
> >Subject: Re: [OpenSAML] local part cannot be "null" when creating a QName
> during unmarshalling an Assertion object
> >
> >
> >Not sure why my Assertion XML is getting stripped.
> >
> >Brent - How can I provide the XML. I am taking another shot
> >
> >
> >
> >

> >>http://localhost:9088 mbrendish
> GETFULLEOPINWRK'>http://web.hsc.syscom.com/">GETFULLEOPINWRK
> -1'>http://web.hsc.syscom.com/">-1
> >
> >
> >
> >

> >thanks
> >Sid
> >
> >
> ________________________________
> From: Sidhartha Priye

> >To: mace-open...@internet2.edu
> >Sent: Mon, March 1, 2010 9:55:28 AM
> >Subject: Re: [OpenSAML] local part cannot be "null" when creating a QName
> during unmarshalling an Assertion object
> >
> >
> >Here is the Assertion Element that was stripped off from my previous post
> >
> >http://localhost:9088 mbrendish
> >
> >
> >thanks
> >Sid
> >
> >
> ________________________________
> From: Sidhartha Priye

> >To: mace-open...@internet2.edu
> >Sent: Mon, March 1, 2010 5:18:20 AM
> >Subject: Re: [OpenSAML] local part cannot be "null" when creating a QName
> during unmarshalling an Assertion object
> >
> >
> >
> >>On 2/26/2010 8:31 PM, Sidhartha Priye wrote:
> >
> >>>
> >>
> >>
> >>
> >>>>[2/26/10 17:16:11:596 EST] 0000001c SystemErr R
> >>java.lang.IllegalArgumentException: local part cannot be "null" when
> >>>>creating a QName
> >>>>[2/26/10 17:16:11:612 EST] 0000001c SystemErr R at

> >>>>javax.xml.namespace.QName.(Unknown Source)


> >>>>[2/26/10 17:16:11:612 EST] 0000001c SystemErr R at

> >>>>javax.xml.namespace.QName.(Unknown Source)


> >>>>[2/26/10 17:16:11:612 EST] 0000001c SystemErr R at
> >>>>org.opensaml.xml.util.XMLHelper.constructQName(XMLHelper.java:433)
> >>>>[2/26/10 17:16:11:612 EST] 0000001c SystemErr R at
> >>>>org.opensaml.xml.util.XMLHelper.getNodeQName(XMLHelper.java:171)
> >>>>[2/26/10 17:16:11:612 EST] 0000001c SystemErr R at
> >>org.opensaml.xml.io.AbstractXMLObjectUnmarshaller.unmarshallAttribute(AbstractXMLObjectUnmarshaller.java:215)
> >>
> >
> >
> >>It's failing trying to construct a QName out of an DOM Attr Node.
> >Either the XML you're sending is malformed in some way, or possibly the
> >way that you parsed the structure into a DOM Element is causing a
> >problem, perhaps it's not namespace-aware or something. I'd confirm
> >exactly what you are sending from the client by getting a trace of the
> >message, just to be sure.
> >
> >
> >
> >
> >
> >This is how I am getting the AssertionElement
> >>>>

Scott Cantor

unread,
Mar 1, 2010, 12:43:32 PM3/1/10
to mace-open...@internet2.edu
> Trace inside the AbstractXMLObjectUnmarshaller.unmarshallAttribute prints
> this "DatatypeHelper.safeTrimOrNullString(attribute.getNamespaceURI())" to
> be null. How can I make my code namespace aware, esp when I am parsing
from
> a SOAP Header.

The namespace is almost always going to be null. The error says the local
part (the attribute's name) is null, that's a completely different thing.

-- Scott


Sidhartha Priye

unread,
Mar 1, 2010, 2:21:42 PM3/1/10
to mace-open...@internet2.edu
Added some more trace:

[3/1/10 13:26:34:209 EST] 0000001d SystemOut O Starting to
unmarshall DOM element

{}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion

[3/1/10 13:26:34:209 EST] 0000001d SystemOut O Unmarshalling
attributes of DOM Element

{}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion

[3/1/10 13:26:34:209 EST]] 0000001c SystemOut O Name: ID="_33776a319493ad607b7ab3e689482e45"
[3/1/10 13:26:34:209 EST] 0000001d SystemOut O Node name: ID
[3/1/10 13:26:34:209 EST]] 0000001c SystemOut O local name: null
[3/1/10 13:26:34:209 EST] 0000001d SystemOut O Node
value: _33776a319493ad607b7ab3e689482e45
[3/1/10 13:26:34:209 EST] 0000001d SystemOut O Node type: 2

So it is trying to unmarshall the "ID" attribute of the Assertion Element. Clearly we can print out the NodeName of the attribute but localname is null. For that reason XMLHelper.getNodeQName(attribute)) throws the error.

Per the documentation of getLocalNamepublic String getLocalName()
Returns the local part of the qualified name of this node.
For nodes of any type other than ELEMENT_NODE and ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, such as createElement from the Document interface, this is always null.
Since:
DOM Level 2

Here is my assertion element for reference.

<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="_33776a319493ad607b7ab3e689482e45" IssueInstant="2010-03-01T08:01:48.944Z" Version="2.0"><saml2:Issuer>http://localhost:9088</saml2:Issuer><saml2:Subject><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">mbrendish</saml2:NameID></saml2:Subject></saml2:Assertion></wsse:Security></soap:Header>

How can I ensure that the attribute has a localname???

thanks
Sid


----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu

Scott Cantor

unread,
Mar 1, 2010, 3:10:33 PM3/1/10
to mace-open...@internet2.edu
> Per the documentation of getLocalNamepublic String getLocalName()
> Returns the local part of the qualified name of this node.
> For nodes of any type other than ELEMENT_NODE and ATTRIBUTE_NODE and nodes
> created with a DOM Level 1 method, such as createElement from the
Document
> interface, this is always null.

Sounds pretty clear, you're using DOM1 instead of DOM2/DOM3 and your parsing
code isn't namespace aware.

-- Scott


Sidhartha Priye

unread,
Mar 1, 2010, 4:04:04 PM3/1/10
to mace-open...@internet2.edu
Thanks Scott for the great suggestion. However I checked and I am using SAAJ1.2 which is DOM2 compliant. Besides I have the JAXP (xercesImpl-2.9.1.jar, xalan-2.7.1.jar, xml-apis-2.9.1.jar) that is OpenSAML2.3 compatible. That being said, it is a good time to have my libraries verified. Anything that jumps out??

Inside the WAS endorsed library (C:\IBM\WAS\java\jre\lib\endorsed)
resolver-2.9.1.jar,
serializer-2.9.1.jar,
xalan-2.7.1.jar,
xercesImpl-2.9.1.jar,
xml-apis-2.9.1.jar,
saaj-api.jar,
saaj-impl.jar

Inside the WEB-INF/lib (Parent Last)

aopalliance-1.0.jar
spring-beans-2.5.6.jar
spring-context-2.5.6.jar
spring-core-2.5.6.jar
spring-web-2.5.6.jar

commons-codec-1.3.jar
commons-collections-3.2.1.jar
commons-configuration-1.5.jar
commons-lang-2.4.jar
commons-logging-1.1.1.jar
commons-pool-1.5.2.jar
joda-time-1.6.jar
log4j.jar

cxf-2.2.6.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.6.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.12.jar
jaxen-1.1.jar
jetty-6.1.21.jar
jetty-util-6.1.21.jar
neethi-2.0.4.jar

opensaml-2.3.0.jar
openws-1.3.0.jar
slf4j-api-1.5.10.jar
slf4j-jdk14-1.5.10.jar
velocity-1.5.jar
bcprov-jdk15-145.jar
xmltooling-1.2.1.jar

wss4j-1.5.8.jar
wstx-asl-3.2.9.jar
xmlbeans-2.4.0.jar
xml-resolver-1.2.jar
XmlSchema-1.4.5.jar
xmlsec-1.4.3.jar

Also, how do I make this code namespace aware.

DefaultBootstrap.bootstrap();
// check for SOAP Header
SOAPHeader sh = smc.getMessage().getSOAPHeader();


thanks
Sid

----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu
> Sent: Mon, March 1, 2010 3:10:33 PM
> Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

Scott Cantor

unread,
Mar 1, 2010, 4:09:59 PM3/1/10
to mace-open...@internet2.edu
> Thanks Scott for the great suggestion. However I checked and I am using
> SAAJ1.2 which is DOM2 compliant. Besides I have the JAXP (xercesImpl-
> 2.9.1.jar, xalan-2.7.1.jar, xml-apis-2.9.1.jar) that is OpenSAML2.3
> compatible. That being said, it is a good time to have my libraries
> verified. Anything that jumps out??

I didn't say your libraries weren't aware, I said your parsing code isn't.

> Also, how do I make this code namespace aware.
>
> DefaultBootstrap.bootstrap();
> // check for SOAP Header
> SOAPHeader sh = smc.getMessage().getSOAPHeader();

None of that code has anything to do with the bug. Whatever is doing the XML
parsing is not using the proper settings before doing so.

-- Scott


Sidhartha Priye

unread,
Mar 1, 2010, 4:20:46 PM3/1/10
to mace-open...@internet2.edu
Thanks Scott,
I am just a little unclear when you say "Whatever is doing XML Parsing is not using the proper settings". How can I control that. I have the Assertion Element that I pass into the Unmarshaller(Element) at which point of time I dont have control how its getting parsed and unmarshalled. To be honest I am a couple of days old into SAML. So if you can point here with respect to the code where I am going wrong, that will be more helpful -

Here is all the code that is involved.

DefaultBootstrap.bootstrap();
SOAPHeader sh = smc.getMessage().getSOAPHeader();
// check for wsse:security element under SOAP Header
Node wsseElement = sh.getFirstChild();

if (wsseElement == null || !"Security".equals(wsseElement.getLocalName())
|| !WS_SECURITY_URI.equals(wsseElement.getNamespaceURI())) {
throw createSOAPFaultException("Missing or invalid WS-Security Header",
true);
}

// check for SAML assertion under wsse:security element
assertionElement = (Element) wsseElement.getFirstChild();

if (assertionElement == null
|| !"Assertion".equals(assertionElement.getLocalName())
|| !SAMLConstants.SAML20_NS.equals(assertionElement.getNamespaceURI())) {
throw createSOAPFaultException("Missing or invalid SAML Assertion", true);
}

Assertion samlAssertion =
(Assertion) unmarshall(assertionElement);
.....................
.....................
protected static XMObject unmarshall(Element samlElem) {
UnmarshallerFactory unmarshallerfactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerfactory.getUnmarshaller(samlElem);

try {

XMLObject xmlObject = unmarshaller.unmarshall(samlElem); //Error is being thrown here which is calling the underlying SAML APIs.

out.println("SAML document root element unmarshalled");
return xmlObject;
} catch (UnmarshallingException e) {
out.println("Unable to unmarshall XML DOM"+e);
}
return null;
}

----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu
> Sent: Mon, March 1, 2010 4:09:59 PM
> Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

Scott Cantor

unread,
Mar 1, 2010, 4:30:44 PM3/1/10
to mace-open...@internet2.edu
> I have the Assertion
> Element that I pass into the Unmarshaller(Element) at which point of time
I
> dont have control how its getting parsed and unmarshalled.

That is not parsing the XML. That's unmarshalling objects from a DOM. The
DOM already exists. Parsing is what happens when you go from XML to a DOM
tree.

> To be honest I am a couple of days old into SAML.

This has nothing to do with SAML or OpenSAML.

> So if you can point here with respect to the
> code where I am going wrong, that will be more helpful -
> Here is all the code that is involved.

No, it isn't. You're missing all of the code that is giving you these
objects:

> SOAPHeader sh = smc.getMessage().getSOAPHeader();
> // check for wsse:security element under SOAP Header
> Node wsseElement = sh.getFirstChild();

The DOM is already broken at that point because it was parsed without
namespace awareness.

-- Scott


Sidhartha Priye

unread,
Mar 1, 2010, 4:44:16 PM3/1/10
to mace-open...@internet2.edu
Aah, sorry...you are right...when you meant parsing the XML I was relating it to parsing the SOAPHeader which represent a DOM element. Here is the client side that builds the DOM. This is the client side JAX WS Handler that injects the SAML into the SOAPHeader.

DefaultBootstrap.bootstrap();

SOAPMessage message = smc.getMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
Name wsseHeaderName = soapEnvelope.createName("Security",
"wsse", WS_SECURITY_NS_URI);
if (soapEnvelope.getHeader() == null) {

soapEnvelope.addHeader();
}

SOAPHeaderElement securityElement = soapEnvelope.getHeader()
.addHeaderElement(wsseHeaderName);

Assertion assertion = (Assertion) Configuration.getBuilderFactory().
getBuilder(Assertion.DEFAULT_ELEMENT_NAME)
.buildObject(Assertion.DEFAULT_ELEMENT_NAME);

assertion.setVersion(SAMLVersion.VERSION_20);
assertion.setID("_33776a319493ad607b7ab3e689482e45"); // in reality, must be unique for all assertions
assertion.setIssueInstant(new DateTime());

Issuer myIssuer = (Issuer) Configuration.getBuilderFactory().
getBuilder(Issuer.DEFAULT_ELEMENT_NAME)
.buildObject(Issuer.DEFAULT_ELEMENT_NAME);

myIssuer.setValue("http://localhost:9088");
assertion.setIssuer(myIssuer);

NameID myNameID = (NameID) Configuration.getBuilderFactory().
getBuilder(NameID.DEFAULT_ELEMENT_NAME)
.buildObject(NameID.DEFAULT_ELEMENT_NAME);

myNameID.setValue("mbrendish");
myNameID.setFormat(NameIDType.X509_SUBJECT);

Subject mySubject = (Subject)Configuration.getBuilderFactory().
getBuilder(Subject.DEFAULT_ELEMENT_NAME)
.buildObject(Subject.DEFAULT_ELEMENT_NAME);

mySubject.setNameID(myNameID);
assertion.setSubject(mySubject);
Element assertionElement = null;
try {
assertionElement =
Configuration.getMarshallerFactory().getMarshaller(assertion.getElementQName())
.marshall(assertion);
} catch (MarshallingException e) {
e.printStackTrace();
}

securityElement.appendChild(soapPart.importNode(
assertionElement, true));

//Print out the outbound SOAP message to System.out
message.writeTo(System.out);
System.out.println("");

Here is the WSClient

Service service = Service.create(SERVICE_NAME);
HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver();
service.setHandlerResolver(handlerResolver);

// Endpoint Address
String endpointAddress = "http://localhost:9088/bpm-servicesCXF/services/IBpmService";
try {
java.net.URL url = new URL(endpointAddress);
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

IBpmService client = service.getPort(IBpmService.class);

Map<String, Object> requestContext = ((BindingProvider)client).getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointAddress);
requestContext.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);

String username = "ewrertert";
String password = "hdfuhgdg";
String category = "GETFULLEOPINWRK";
int max = -1;
Properties arguments = null;
String response =null;
try {
response = client.findTaskList(category, arguments, max);
System.out.println("Response: " + response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

thanks
Sid

----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu
> Sent: Mon, March 1, 2010 4:30:44 PM
> Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

Scott Cantor

unread,
Mar 1, 2010, 4:54:47 PM3/1/10
to mace-open...@internet2.edu
> Aah, sorry...you are right...when you meant parsing the XML I was relating
> it to parsing the SOAPHeader which represent a DOM element. Here is the
> client side that builds the DOM. This is the client side JAX WS Handler
that
> injects the SAML into the SOAPHeader.

That's not where the XML is being parsed by your server. If the XML is
parsed by something you don't control, then you're going to have to get
control to fix it.

-- Scott


Sidhartha Priye

unread,
Mar 2, 2010, 1:31:30 PM3/2/10
to mace-open...@internet2.edu
It appears the DOM parsing issue is with the CXF library distribution not being namespace aware. They have applied the fix and would be available in tomorrow's snapshot that I will test out.

That being said I have a dilemma I am trying to unravel:

I am trying to come up with the right combination of CXF WS+Spring+OpenSAML 2.3 using IBM JDK1.5/WAS6.1
Your documentation suggest not using SUN JAXP implementation and instead recommends Xerces, Xalan and xmlapis shipped with OpenSAML endorsed in the IBM JDK runtime. So I have that in place. However recent CXF distribution tends to use the SAAJ 1.3.2 libraries that does not work with IBM JDK 1.5/WAS 6.1. So I have to endorse the SAAJ1.2 libraries in WAS/IBM JDK.

If I do that I am running into the following -
Exception in thread "main" java.lang.NoSuchMethodError: javax/xml/soap/SOAPFault.setFaultCode(Ljavax/xml/namespace/QName;)V
at org.apache.cxf.binding.soap.saaj.SAAJInInterceptor.handleMessage(SAAJInInterceptor.java:154)
at org.apache.cxf.jaxws.handler.soap.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:78)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.createProtocolMessageContext(SOAPHandlerInterceptor.java:236)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessageInternal(SOAPHandlerInterceptor.java:144)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:119)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:69)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)

Since I am not dropping the jaxp-ri-1.4.2 jar (cannot use with OpenSAML) which has the QName it is complaining. Is there a replacement jar which contains the QName class. For now I can drop in the stax-api-1.0.1.jar (which has QName) which is not allowed to be used with newer CXF distribution. Woodstox doesnot have a QName class.

So if you see this is a deployer's nightmare trying to mix and match to work with CXF+Spring+OpenSAML on Websphere. + IBM JDK 1.5

Any suggestions/tips will be greatly appreciated

thanks
Sid


----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu
> Sent: Mon, March 1, 2010 4:54:47 PM
> Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

Scott Cantor

unread,
Mar 2, 2010, 9:04:22 PM3/2/10
to mace-open...@internet2.edu
> Since I am not dropping the jaxp-ri-1.4.2 jar (cannot use with OpenSAML)
> which has the QName it is complaining.

Maybe I'm misreading your error, but that looks like it's missing some kind
of SOAP method, not the JAXP QName class.

-- Scott


Sidhartha Priye

unread,
Mar 3, 2010, 1:46:09 PM3/3/10
to mace-open...@internet2.edu
Scott,

I have managed to resolve the issues on my end and can assert and validate a SAML2.3 token to the CXF webservice deployed on Websphere 6.1. The issue turned out to be more a configuration one with some jars that were on the classpath that was probably building a broken DOM. Its a nightmare getting to deploy Spring/SAML/CXF on to Websphere 6.1 with the SUN jars in the mix.

As for the SOAPFault not finding a method , it appears to be specifically isolated to one version of CXF (2.2.6). I can get it to work with no issues using cxf-incubator.2.0

That being said, I am now trying to implement a RESTful SAML approach and looking for directions

Thanks for all your help.

----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu
> Sent: Tue, March 2, 2010 9:04:22 PM
> Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

Scott Cantor

unread,
Mar 3, 2010, 4:35:39 PM3/3/10
to mace-open...@internet2.edu
> I have managed to resolve the issues on my end and can assert and validate
a
> SAML2.3 token to the CXF webservice deployed on Websphere 6.1. The issue
> turned out to be more a configuration one with some jars that were on the
> classpath that was probably building a broken DOM. Its a nightmare getting
> to deploy Spring/SAML/CXF on to Websphere 6.1 with the SUN jars in the
mix.

One of the reasons for that is that people don't provide back any
documentation on all the esoteric combinations they get working even though
there's a wiki that anybody can register in and edit.

> That being said, I am now trying to implement a RESTful SAML approach and
> looking for directions

REST has limited support for message-based security models. OAuth's
unrelated portions that are really attempting to fix HTTP security are an
example of one approach, but not one that SAML can adapt to because
assertions don't fit into HTTP headers.

Our (Shibboleth's) approach has been to stick to models based on
session-level security that are consistent with web SSO, posting assertions
to get back a cookie and then relying on the cookie. This happens to be
compatible with existing SP software and allows REST based services to be
secured with the same code as browser facing services, or offer both at
once.

https://spaces.internet2.edu/display/ShibuPortal/Home

-- Scott


Sidhartha Priye

unread,
Mar 3, 2010, 5:15:09 PM3/3/10
to mace-open...@internet2.edu
Thanks Scott, Will look into that. Also will certainly add my findings to the wiki. I have to write one anyhow for my internal use.


As for RESTful approach, I read on one of the blogs
http://weblogs.asp.net/cibrax/archive/2009/03/06/brokered-authentication-for-rest-active-clients-with-saml.aspx

that you can inject the token in the HTTP Header (Authorization field) .


WebRequest webRequest = HttpWebRequest.Create(address);
webRequest.Method = "GET";
webRequest.Headers["Authorization"] = token;

and implement a message interceptor on the Relying party Service end that will process the token and validate the request

result.Interceptors.Add(new MessageInterceptors.SamlAuthenticationInterceptor(new TrustedIssuerNameRegistry()));

Is this viable approach given this blog talks about Geneva as their underlying implementation.


Somewhere else I read about RESTful STS which talks about a similar approach -

http://ws-security.blogspot.com/2010/02/integrating-rest-clients-with-sts-for.html

From the blog -


"In such scenarios, following flow would be applicable

1. REST
client acquires token from the STS server preferably through REST
binding of STS, but any other supported binding should also be okay.
2. Once it receives the token, it adds it to the "Authorization" HTTP header of the REST request.
3. REST service receives the request, and a
security interceptor(agent) picks up the token to check for access
validity. The interceptor can optionally assert the identity into the
service for identity propagation needs."
I am speculating when they are talking about tokens, they are referring to SAML assertions. If that being the case, you did mention that SAML cannot adapt to OAuth because Assertions cannot be serialized into headers.

Can you please throw some more light.

thanks
Sid

----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu
> Sent: Wed, March 3, 2010 4:35:39 PM
> Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

Scott Cantor

unread,
Mar 3, 2010, 5:23:19 PM3/3/10
to mace-open...@internet2.edu
> As for RESTful approach, I read on one of the blogs
> http://weblogs.asp.net/cibrax/archive/2009/03/06/brokered-authentication-
> for-rest-active-clients-with-saml.aspx
>
> that you can inject the token in the HTTP Header (Authorization field) .

Assuming you're ok with it breaking on a lot of web servers, sure. Headers
are quite limited in size in many configurations.

> Is this viable approach given this blog talks about Geneva as their
> underlying implementation.

If it works on IIS, then presumably they've left the header limits very
relaxed, but it won't fly on Apache in most cases.

> I am speculating when they are talking about tokens, they are referring to
> SAML assertions. If that being the case, you did mention that SAML cannot
> adapt to OAuth because Assertions cannot be serialized into headers.

You can put anything into a header but that doesn't make it fit. OAuth is
optimized for small bearer tokens issued by the service you're sending the
request to. Once you split the issuer off, you need a standard format, and
you need semantics that bloat the size. More importantly, you need a
signature and you're blown.

Besides that, you're gaining...nothing. Most use cases include messages back
and forth and it's not efficient to process a signed token on every request,
and you'll end up with a cookie-like thing anyway. So the choice is an
inefficient mechanism that's proprietary and doesn't support sessions
directly, or a mechanism based on a standard SAML profile and assumes
session semantics already provided by the SSO software.

-- Scott


Brent Putman

unread,
Mar 3, 2010, 7:26:59 PM3/3/10
to mace-open...@internet2.edu, Sidhartha Priye
Yes, a quick glance a the Java docs for javax.xml.soap.SOAPFault shows
that the setFaultCode(QName) was introduced in the SAAJ 1.3 API. You
(or CXF etc) must at runtime be using an earlier version.


On 3/3/2010 1:46 PM, Sidhartha Priye wrote:
>
> As for the SOAPFault not finding a method , it appears to be specifically isolated to one version of CXF (2.2.6). I can get it to work with no issues using cxf-incubator.2.0
>
>

Sidhartha Priye

unread,
Mar 4, 2010, 1:43:48 PM3/4/10
to mace-open...@internet2.edu
Thanks Scott for the detailed explanation,

In our case I am not sure if I can completely integrate the Shibboleth's WebSSO solution you are proposing because there is already IDP initialized through a third party IDP that provides us the NTLM token obtained through a windows logon. Our custom Spring SSO solution gives us the User Token and more specifically the principal.

So all we have to do now is issue an HTTP POST (preferred to HTTPRedirect which uses a GET) binding to the Service Provider (SP) in the form of a <samlp:Response> and pass the serialized encoded signed assertion using the protocol message exchange.

So here is what I am thinking I need to do

1. Build the Assertion myself (rather than through asamlp:AuthnRequest to an IDP)
2. Serialize and encode the XML message and push it into the samlResponse hidden field (using HTTPClient. I think you already have a library that will give me an instance of HTTPClient through the SAMLSession)
3. Request the assertion consumer service with samlpResponse
4. Service creates a security context (is this the session affinity for future requests) and redirects to the target resource.

Please confirm if this approach will work and I am looking for code samples to get me started.

thanks
Sid

----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu
> Sent: Wed, March 3, 2010 5:23:19 PM
> Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

Tom Delorenzi

unread,
Mar 4, 2010, 1:47:06 PM3/4/10
to mace-open...@internet2.edu
I have completed my saml code which talks to a responder, gets an assertion and validates the signature. Im rejecting the signature(which is coming from a test perl script). Is there some easy way to verify if my code is working right? Any way to feed myself a pre-canned response or something that I know 100% is valid?

Thanks.

Scott Cantor

unread,
Mar 4, 2010, 3:02:12 PM3/4/10
to mace-open...@internet2.edu

Normally you need to determine if the instance that's failing is valid in a
known working implementation and then you'll know if it's your code, theirs,
or the transport. There are exhaustive threads on this in the archive.

-- Scott


Tom Delorenzi

unread,
Mar 4, 2010, 3:04:27 PM3/4/10
to mace-open...@internet2.edu
Unfortunately both sides of the picture here are new development and so neither is known to be good :)

Scott Cantor

unread,
Mar 4, 2010, 3:11:53 PM3/4/10
to mace-open...@internet2.edu
> Unfortunately both sides of the picture here are new development and so
> neither is known to be good :)

I didn't assume it was, I said you need to supply the suspect XML into a
known good implementation like xmlsec's online tool or Oxygen's verifier to
isolate the failure, though only SAML 2 documents will usually work with
them. The samlsign utility in opensaml-c is also an option, and works with
either protocol version.

-- Scott


Scott Cantor

unread,
Mar 4, 2010, 4:12:16 PM3/4/10
to mace-open...@internet2.edu
> In our case I am not sure if I can completely integrate the Shibboleth's
> WebSSO solution you are proposing because there is already IDP initialized
> through a third party IDP that provides us the NTLM token obtained through
a
> windows logon. Our custom Spring SSO solution gives us the User Token and
> more specifically the principal.

If you're using Windows security, seems like you're done. No SAML needed.

> So all we have to do now is issue an HTTP POST (preferred to HTTPRedirect
> which uses a GET) binding to the Service Provider (SP) in the form of a
> <samlp:Response> and pass the serialized encoded signed assertion using
the
> protocol message exchange.

I don't know how you think you'd get an assertion or what would be in it, or
how you think you're going to secure it all, but you're describing the
standard browser SSO profile response, and I suggested using a variant of
that designed for non-browsers, so I don't know why you think it doesn't
apply.

> So here is what I am thinking I need to do
>
> 1. Build the Assertion myself (rather than through asamlp:AuthnRequest
> to an IDP)

Who is "myself"? An IdP? A client can't just make up an assertion, it serves
no purpose to do so.

-- Scott


Sidhartha Priye

unread,
Mar 4, 2010, 11:51:38 PM3/4/10
to mace-open...@internet2.edu
Scott,

I completely agree with you. Building an Assertion on the client end does not serve any purpose, not without an IDP.

However we are operating within the limitations laid out by the client. They prefer to not change their preferred approach of using Spring NTLM to render a UsernamePasswordToken. However they insist on using SAML (since it is a standard) to propagate a signed SAML token in the HTTP call made out to the RESTful service. They want to embed the Principal (through NameID) in the SAML assertion, sign it and pass it into the http request. On the service end they want to validate the signature and retrieve the Principal to be used further downstream for logging into Filenet Content Engine using a Websphere Custom Login Module that operates on Identity assertion with trust validation.

Given all that I mentioned, I am struggling to (for lack of documentation unless I missed it) to come up with an approach to issue HTTP calls (using a HTTP Post) and pass along the SAML token. We have historically been using Apache HTTPClient to issue the Get and Post requests to the REST services.
For .e.g.

String samlAction = "http://localhost:9088/SAML2/SSO/POST";

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new NameValuePair(PARAM_ACTION, samlAction));
params.add(new NameValuePair (PARAM_SAMLP_RESPONSE, samlpResponseStart)); //hidden form field.

method = new PostMethod(url.toString());
method.setQueryString((NameValuePair[])params.toArray(new NameValuePair[0]));
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(ConfigManager.getInstance().getServiceRetry(), false));

HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setConnectionTimeout(TIME_OUT);

url += "?" + method.getQueryString();
if (logger.isInfoEnabled()) logger.info("BPM10038", url);

statusCode = client.executeMethod(method);

Now the challenge is to integrate our existing setup using HTTPClient with one of the SSO Profiles you mentioned. Can I leverage the BasicSAMLMessageContext and pass that into the samlpResponse parameter. Also how can this accomplished through an HttpClient interface.

HTTPPostEncoder encoder = new HTTPPostEncoder(velocityEngine, "/templates/saml2-post-binding.vm");
encoder.encode(messageContext);

thanks for all the help so far. Really appreciate your time.
Sid


----- Original Message ----
> From: Scott Cantor <cant...@osu.edu>
> To: mace-open...@internet2.edu
> Sent: Thu, March 4, 2010 4:12:16 PM
> Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
>

> > In our case I am not sure if I can completely integrate the Shibboleth's
> > WebSSO solution you are proposing because there is already IDP initialized
> > through a third party IDP that provides us the NTLM token obtained through
> a
> > windows logon. Our custom Spring SSO solution gives us the User Token and
> > more specifically the principal.
>
> If you're using Windows security, seems like you're done. No SAML needed.
>
> > So all we have to do now is issue an HTTP POST (preferred to HTTPRedirect
> > which uses a GET) binding to the Service Provider (SP) in the form of a

Chandra Tondepu

unread,
Mar 5, 2010, 10:13:44 AM3/5/10
to mace-open...@internet2.edu
To post a SAML Request
 
 <form method="post" action="https://idp.example.org/SAML2/SSO/POST" ...>
   <input type="hidden" name="SAMLRequest" value="request" />
   ...
   <input type="submit" value="Submit" />
</form>
 
In your case, it must be a bearer token that you are trying to propogate from one service to another service.  So you can send that as SAMLResponse to the other system.
 
snip2>>
 
<form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...>
   <input type="hidden" name="SAMLResponse" value="response" />
   ...
   <input type="submit" value="Submit" />
</form>
<<snip2
 
You can use the above snip.
 
Regards, Chandra.

Sidhartha Priye

unread,
Mar 5, 2010, 1:12:38 PM3/5/10
to mace-open...@internet2.edu
Thanks Chandra for the suggestion. Like I mentioned we have a third party IDP that is windows based that gives us access to the Spring NTLM token. So we cannot post a SAML request to the SAML based IDP providerand thus cannot get back a SAMLResponse which contains the Assertion.

So I opted for the other approach which was to build the Assertion ground up that includes the Principal (from Spring NTLM token) and Issuer. Once I did that I was able to serialize the SAML token, deflate it and then Base64 encode it and pass into the "Authorization" key of the HTTPHeader. Used HTTPClient's getMethod to serve the request. On the servlet end I retrieved the token from the header, decoded it, inflated it and then deserialized it.  Once I did that I was able to validate the signature and retrieve the Principal through the NameID field which is used for the second hop into IBM Filenet Content Engine.

I still need to implement a session affinity on the REST service to validate subsequent incoming requests based on certain conditions stated in the Assertion. This works for now. Once we make a shift to a formal SAML IDP (whenever the client agress), we will start to incorporate the IDP Initialized SSO Profile.

Thanks to everyone for their help and time

regards
Sid

Scott Cantor

unread,
Mar 5, 2010, 1:24:39 PM3/5/10
to mace-open...@internet2.edu
> However we are operating within the limitations laid out by the client.
They
> prefer to not change their preferred approach of using Spring NTLM to
render
> a UsernamePasswordToken. However they insist on using SAML (since it is a
> standard) to propagate a signed SAML token in the HTTP call made out to
the
> RESTful service. They want to embed the Principal (through NameID) in the
> SAML assertion, sign it and pass it into the http request. On the service
> end they want to validate the signature and retrieve the Principal to be
> used further downstream for logging into Filenet Content Engine using a
> Websphere Custom Login Module that operates on Identity assertion with
trust
> validation.

If you're doing that, make sure you omit any SubjectConfirmation from the
assertion and/or use the sender-vouches method, as it's designed for that
use case of simply claiming the identity from the client end.

-- Scott


Chandra Tondepu

unread,
Mar 5, 2010, 4:18:03 PM3/5/10
to mace-open...@internet2.edu
Scott;  Do you mean to say pass "urn:oasis:names:tc:SAML:2.0:cm:sender-vouches" instead of "urn:oasis:names:tc:SAML:2.0:cm:bearer" in the SAML Assertion, as the primary Identity Provider is not generating this Assertion??

Chandra

 
On Fri, Mar 5, 2010 at 1:24 PM, Scott Cantor <cant...@osu.edu> wrote:
> However we are operating within the limitations laid out by the client.
They
> prefer to not change their preferred approach of using Spring NTLM to
render
> a UsernamePasswordToken. However they insist on using SAML (since it is a
> standard) to propagate a signed SAML token in the HTTP call made out to
the
> RESTful service. They want to embed the Principal (through NameID) in the
> SAML assertion, sign it and pass it into the http request. On the service
> end they want to validate the signature and retrieve the Principal to be
> used further downstream for logging into Filenet Content Engine using a
> Websphere Custom Login Module that operates on Identity assertion with
trust
> validation.

Scott Cantor

unread,
Mar 5, 2010, 4:24:37 PM3/5/10
to mace-open...@internet2.edu
> Scott; Do you mean to say pass "urn:oasis:names:tc:SAML:2.0:cm:sender-
> vouches" instead of "urn:oasis:names:tc:SAML:2.0:cm:bearer" in the SAML
> Assertion, as the primary Identity Provider is not generating this
> Assertion??

Yes, because "bearer" means anybody with possession of it can use it. That's
not what this use case is about. It's about unilaterally trusting the client
to say whatever it wants to say, and no other relying party should think it
should accept the assertion unless it also trusts its client implicitly.

In other words, the rules aren't in the assertion, they're part of the out
of band arrangement.

-- Scott


Sidhartha Priye

unread,
Mar 23, 2010, 12:37:45 PM3/23/10
to mace-open...@internet2.edu, Sidhartha Priye
Scott/Brent,

I had reported that I was able to resolve this issue few weeks back with some configuration setup using (cxf-incubator-2.0); however this issue came back again couple of days back. So I logged this in Apache CXF JIRA tracker and Daniele Kulp (development lead from Apache CXF) resolved this in the latest cxf distribution 2.2.7 based on the clue you had provided. Thanks for that.

So for any one who would like to know the details of my setup that gives me a working solution. Here is the JIRA tracker item that has all the details. Read the last post with all the configuration details to integrate CXF + Open SAML 2.0 on Websphere 6.1 (IBM JDK 1.5). This is a very rare use case that is extremely difficult to accomplish and so the details here will be very useful. Remember WAS 6.1 can only endorse SAAJ1.2 so there are special set of jars required to render WAS to support SAAJ1.3 that is used by recent CXF editions.

Here is the link
https://issues.apache.org/jira/browse/CXF-2725


thanks
Sid


Sent: Mon, March 1, 2010 4:09:59 PM

Subject: RE: [OpenSAML] local part cannot be "null" when creating a QName during unmarshalling an Assertion object
Reply all
Reply to author
Forward
0 new messages