Question

This is my xml document. I want to sign only the userID part using xml signature. I am using xpath transformation to select that particular element.

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
Version="2.0" IssueInstant="2012-05-22T13:40:52:390" ProtocolBinding="urn:oasis:na
mes:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="localhos
t:8080/consumer.jsp">
<UserID>
   xyz
</UserID>
<testing>
   text
</testing>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
   http://localhost:8080/saml/SProvider.jsp
</saml:Issuer>
</samlp:AuthnRequest>


I am using the following code to add the transformations :

transformList.add(exc14nTransform);
 transformList.add(fac.newTransform(Transform.XPATH, new XPathFilterParameterSpec("samlp:AuthnRequest/UserID xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"")));


But I get the following :

Original Exception was javax.xml.transform.TransformerException: Extra illegal t
okens: 'xmlns', ':', 'samlp', '=', '"urn:oasis:names:tc:SAML:2.0:protocol"'


So, I tried removing the xmlns part.

transformList.add(fac.newTransform(Transform.XPATH, new XPathFilterParameterSpec("samlp:AuthnRequest/UserID")));


But it signs the whole document and gives the following message :

com.sun.org.apache.xml.internal.security.utils.CachedXPa
thFuncHereAPI fixupFunctionTable
INFO: Registering Here function


What is the problem?
EDIT
As @Jörn Horstmann said the message is just a log or something like that. Now the problem is that even after giving the xpath query the whole document is signed instead of just the UserID. I confirmed this by changing the value of <testing>element after signing the document. The result is that the document does not get validated(If it signed only the UserID part, then any changes made to <testing> should result in a valid signature .)

Was it helpful?

Solution

This is not a valid xpath expression, there is no way to declare namespace prefixe inside the expression.

samlp:AuthnRequest/UserID xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"

XPathFilterParameterSpec does have another constructor that allows to specify a mapping of namespace prefixes, you could try the following expression:

new XPathFilterParameterSpec("samlp:AuthnRequest/UserID",
    Collections.singletonMap("samlp", "urn:oasis:names:tc:SAML:2.0:protocol"))

Edit:

The message does not seem to be an error, see line 426 here, its log level should probably be lower than INFO though.

I also had a look at the description of xpath filtering:

The XPath expression appearing in the XPath parameter is evaluated once for each node in the input node-set. The result is converted to a boolean. If the boolean is true, then the node is included in the output node-set. If the boolean is false, then the node is omitted from the output node-set.

So the correct xpath expression to only include the UserID in the signature would be self::UserID. But don't ask me if this actually makes sense for a xml signature. The example in the specification seems to use a xpath expression to include everything except the signature element itself:

not(ancestor-or-self::dsig:Signature)

Edit 2:

The correct expression is actually ancestor-or-self::UserID since the filter also has to include the text child nodes of the UserID node.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top