[JXT-58] Add wiki documentation showing integration of OpenSAML with
JAX-RPC Created: 17/May/09 Updated: 17/May/09
Status:
Project:
Component/s:
Fix Version/s:
Open
XMLTooling - Java
None
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Task
Chad La Joie
Unresolved
None
Not Specified
Priority:
Assignee:
Votes:
Minor
Chad La Joie
0
Not Specified
Not Specified
Description
This was provided by Frederik Libert of SMALS.be in this thread: http://groups.google.com/group/opensamlusers/browse_thread/thread/6a79744c24436559/5a39c675d78be14c
It extends the RPC generic handler (javax.xml.rpc.handler.GenericHandler).
It checks the outgoing SOAPBody on clientside for a SAMLRequest, Response or Assertion.
If it finds one, the saml is parsed into opensaml API, it is signed and the SOAPBody child-element containing
the SAML is replaced with a new child-element containing the signed SAML message.
It has no vendor dependent code so I think it can be used in different java-client-webservice-implementations.
You may need to do some tweeking though.
For example, I tested with Weblogic 10.3 and had to set the following system property:
System.setProperty("weblogic.wsee.handler.allowAllModification", "true");
Without this property, you are not allowed to modify the SOAPMessage the way I did.
Some other webservice implementations may not need this handler if they do not break the signature when
building the soapmessage, but even then it might be useful as this handler makes sure that the signature is based
on (and included in) the xml that will eventually be sent to the webservice.
Two final remarks:
- if there are other SOAPHandlers configured on the client after the SamlSignSoapHandler, they may no longer
modify the SOAPBody-content otherwise the SAML signature will be broken.
- if the webservice is secured with WS-Policy or something else that requires the client to sign the entire
SOAPBody or more, the SamlSignSoapHandler must be executed before this signature is set by the client,
otherwise the WS-Policy-signature will be broken.
--- SamlSignSoapHandler.java : begin --package org.eh.sts.wsclient.handler;
import java.util.Properties;
import javax.xml.namespace.QName;
import javax.xml.rpc.handler.GenericHandler;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLRequest;
import org.opensaml.SAMLResponse;
import org.opensaml.SAMLSignedObject;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.eh.sts.wsclient.STSClientException;
import org.eh.sts.wsclient.support.SAMLSignFactory;
/**
* SOAP Handler that signs SAML Messages contained in SOAPBody. <br/> Supports signing of SAML
Requests, Responses and Assertions. <br/>
* Webservice-call must be document-style with the SAML Element as input message.
*
* @author Frederik Libert
*
* @since 1.0.0
*
*/
public class SamlSignSoapHandler extends GenericHandler {
private static final String CRYPTO_FILE = "cryptoFile";
private QName[] headers;
/** cryptographic properties to sign SAML Message. */
Properties crypto;
/**
* @see javax.xml.rpc.handler.GenericHandler#init(javax.xml.rpc.handler.HandlerInfo)
*/
@Override
public void init(HandlerInfo config) {
this.crypto = new Properties();
String cryptoFile = System.getProperty("SamlSignSoapHandler.cryptoFile");
if (cryptoFile == null) {
cryptoFile = (String) config.getHandlerConfig().get(CRYPTO_FILE);
}
if (cryptoFile == null) {
throw new STSClientException("Correct location of file with cryptographic info must be set through
either a System-property or a handler-config parameter");
}
try {
this.crypto.load(SamlSignSoapHandler.class.getResourceAsStream(cryptoFile));
} catch (Exception e) {
throw new STSClientException("Could not load cryptographic properties to sign SAML Message", e);
}
}
/**
*
* @see javax.xml.rpc.handler.GenericHandler#handleRequest(javax.xml.rpc.handler.MessageContext)
*/
public boolean handleRequest(MessageContext context) {
SOAPMessageContext messageContext = (SOAPMessageContext) context;
try {
System.out.println("SamlSignSoapHandler -- signing SAML in SOAPBody ...");
Node nodeBeforeSigning = messageContext.getMessage().getSOAPBody().getFirstChild();
DOMSource source = new DOMSource(nodeBeforeSigning);
SAMLSignedObject request = transformToSAML(source);
SAMLSignFactory.getInstance().sign(request, this.crypto);
System.out.println("SamlSignSoapHandler -- SAML signed");
System.out.println("SamlSignSoapHandler -- Replacing SAML in SOAPBody ...");
Node nodeAfterSigning = request.toDOM();
messageContext.getMessage().getSOAPBody().removeChild(nodeBeforeSigning);
messageContext.getMessage().getSOAPBody().addDocument(nodeAfterSigning.getOwnerDocument());
System.out.println("SamlSignSoapHandler -- SAML replaced");
} catch (Exception e) {
throw new STSClientException("SAML in SOAPBody could not be signed", e);
}
return true;
}
/**
*
* @see javax.xml.rpc.handler.GenericHandler#handleResponse(javax.xml.rpc.handler.MessageContext)
*/
public boolean handleResponse(MessageContext context) {
return true;
}
/**
*
* @see javax.xml.rpc.handler.GenericHandler#getHeaders()
*/
public QName[] getHeaders() {
return headers;
}
private SAMLSignedObject transformToSAML(Source request) {
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
DOMResult result = new DOMResult();
transformer.transform(request, result);
Node samlNode = result.getNode().getFirstChild();
if (samlNode.getLocalName().equals("Request")) {
return new SAMLRequest((Element) samlNode);
}
if (samlNode.getLocalName().equals("response")) {
return new SAMLResponse((Element) samlNode);
}
if (samlNode.getLocalName().equals("Assertion")) {
return new SAMLAssertion((Element) samlNode);
}
throw new IllegalArgumentException("Not supported source (RootNode=" + samlNode.getLocalName()
+ ")");
} catch (Exception e) {
throw new STSClientException("Problem transforming source to SAML", e);
}
}
}
--- SamlSignSoapHandler : end --to configure the handlerchain, I used the vendor specific xml-file but I think there are standard ones also (not
sure though).
--- ClientHandlerChain.xml : begin ---
<weblogic-wsee-clientHandlerChain xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:j2ee="http://java.sun.com/xml/ns/j2ee">
<handler>
<j2ee:handler-name>SamlSignSoapHandler</j2ee:handler-name>
<j2ee:handler-class>org.eh.sts.wsclient.handler.SamlSignSoapHandler</j2ee:handler-class>
<j2ee:init-param>
<j2ee:param-name>cryptoFile</j2ee:param-name>
<j2ee:param-value>/crypto.properties</j2ee:param-value>
</j2ee:init-param>
</handler>
</weblogic-wsee-clientHandlerChain>
--- ClientHandlerChain.xml : end ---
[JXT-47] Should avoid emitting the unnecessary xml namespace declarations
when marshalling Created: 17/Feb/09 Updated: 22/Jun/10
Status:
Project:
Component/s:
Fix Version/s:
In Progress
XMLTooling - Java
Marshalling
1.2.1
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Improvement
Brent Putman
Unresolved
None
Not Specified
Priority:
Assignee:
Votes:
Minor
Brent Putman
0
Not Specified
Not Specified
Description
We are unnecessarily declaring the "xml" namespace prefix when elements have attributes from
this namespace, such as "xml:lang". While technically legal, this apparently causes problems
with some software, for example the current C++ Apache xmlsec library, which (incorrectly)
includes the namespace node during canonicalization, causing signature validation to fail.
For example this input:
<Organization>
<OrganizationName xml:lang="en">Urizen2</OrganizationName>
<OrganizationDisplayName xml:lang="en">Fox's test system </OrganizationDisplayName>
<OrganizationURL xml:lang="en">http://urizen2.cac.washington.edu/</OrganizationURL>
</Organization>
Results in this output:
<Organization>
<OrganizationName xmlns:xml="http://www.w3.org/XML/1998/namespace"
xml:lang="en">Urizen2</OrganizationName>
<OrganizationDisplayName xmlns:xml="http://www.w3.org/XML/1998/namespace"
xml:lang="en">Fox's test system </OrganizationDisplayName>
<OrganizationURL xmlns:xml="http://www.w3.org/XML/1998/namespace"
xml:lang="en">http://urizen2.cac.washington.edu/</OrganizationURL>
</Organization>
Comments
Comment by Chad La Joie [ 20/Aug/09 ]
Fixed in rev 654
Comment by Brent Putman [ 22/Apr/10 ]
Reopening per JXT-64.
Comment by Brent Putman [ 23/Apr/10 ]
Tthis was supposedly fixed in August 2009 and is in xmltooling 1.2.1.
A quick test shows that Chad's fix seems to work, for the simple case of say building a new
EntitiesDescriptor with an Organization/OrganizationName. It doesn't express the xmlns:xml
even if you add explicitly a Namespace instance for it to the XMLObject.
Scott, can you comment on under what scenarios you are seeing this? Is it primarily SAML
metadata, which might have been parsed from XML and then remarshalled and serialized? Just
wondering if there's something going on with the DOM itself, perhaps the parser is doing
something unexpected.
Comment by Brent Putman [ 23/Apr/10 ]
So this is very strange. I've confirmed that this does occur under at least one condition.
As above, it does not occur with a simple build-from-scratch and marshall and serialize.
It does not occur with a simple parse from XML, and then just re-serialize, whether against the
cached DOM from getDOM() or by re-marshalling, which has the effect of adopting the existing
cached DOM element tree into a new Document.
However, it *does* occur when you parse from XML, drop the DOM via releaseDOM() and
releaseChildrenDOM(true), and then marshall and serialize. It is not immediately clear to me
how/why this is different from the build-from-scratch case, since the DOM is supposedly
dropped. Need to do some in-depth debugging....
In any case, this is pretty much what the SAML metadata providers do: they drop the DOM
after parsing. The file-backed ones then (I think) remarshall and reserialize that XMLObject. So
the file-backup version would contain the unnecessary xmlns:xml declarations.
Comment by Scott Cantor [ 23/Apr/10 ]
Sorry for the duplicate, I thought I remembered filing this but I couldn't find it.
I didn't actually see this, but I got a report from Gabriel Sroka that the metadata serialized as
backup by these versions was still carrying it:
IdP v 2.1.3
DS v 1.1.0
Checking the POMs, 2.3.1 appears to be based on xmltooling 1.2.1.
His report was that it was specific to the metadata backup. Sounds like you reproduced it.
Comment by Brent Putman [ 24/Apr/10 ]
Just wanted to confirm... I didn't notice this when I first looked at it, but what I'm actually
seeing in terms of reproducing is that the XML namespace that's getting declared in the
parse/unmarshall/drop DOM case is that the XML namespace, on marshalling, is actually being
set to the default namespace, not the "xml" prefix, eg:
This input:
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<md:Organization>
<md:OrganizationName xml:lang="en">Parsed University</md:OrganizationName>
</md:Organization>
</md:EntityDescriptor>
produces this output:
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<md:Organization>
<md:OrganizationName xmlns="http://www.w3.org/XML/1998/namespace"
xml:lang="en">Parsed University</md:OrganizationName>
</md:Organization>
</md:EntityDescriptor>
Which is of course completely invalid wrt the namespace spec.
At first glance I missed that the "xml" prefix wasn't on the declaration. I don't know if this is
actually the problem that was actually reported - Scott, so you have any way to confirm with
this guy?
This is happening b/c when the "xml:lang" attribute is parsed, the parser does know that its
namespace is the XML namespace (it's built-in), and so Attr#getNamespaceURI produces the
right value. However, our code then just does a Attr#lookupPrefix on that namespace URI, and
in this case it returns null, rather than "xml". The code then unconditionally creates and adds a
new Namespace with the null prefix. Chad's previous fix in the marshaller doesn't catch this,
because the conditional logic there is on matching the "xml" prefix of the Namespace, not the
namespace URI, so the Namespace with the null prefix makes it through.
I think we should probably fix in both places: 1) fix the Namespace being added with the null
prefix in the unmarshaller, and also have the marshaller check both the namespace prefix and
URI. That way we cover all the bases.
I'll make those changes, but leave this open to do some more testing.
Comment by Scott Cantor [ 24/Apr/10 ]
It's not what he reported. The XML he was seeing is here:
http://wayf.calstate.edu/metadata/InCommon-metadata.xml
I think that's serialized output from the DS. The 1.1 DS does predate the fix (it used xmltooling
1.2.0). My guess is he was confused about the IdP not having been fixed, and assumed it hadn't
since the DS he was using hadn't. I'll ask him to take a look.
Comment by Chad La Joie [ 24/Apr/10 ]
Quite likely. The DS hasn't been updated in quite a while.
Comment by Brent Putman [ 25/Apr/10 ]
I just tested this with the file-backed HTTP metadata provider in the 2.1.5 IdP, which uses
xmltooling 1.2.1, and unfortunately it's still exhibiting the buggy behavior in the backup file:
<Organization>
<OrganizationName xmlns:xml="http://www.w3.org/XML/1998/namespace"
xml:lang="en">The Ohio State University</OrganizationName>
<OrganizationDisplayName xmlns:xml="http://www.w3.org/XML/1998/namespace"
xml:lang="en">Ohio State University</OrganizationDisplayName>
<OrganizationURL xmlns:xml="http://www.w3.org/XML/1998/namespace"
xml:lang="en">http://www.osu.edu/</OrganizationURL>
</Organization>
I did a little more digging and turns out I was wrong about the behavior of the file-backed
metadata provider. Looks like it actually writes out the backing file *before* the DOM gets
dropped, in fetchMetadata(). And the way writeMetadataToFile() is implemented, it actually
doesn't marshall it at all in that case, it just pulls it from getDOM():
// The metadata object should still have its DOM
// but we'll create it if it doesn't
if (metadata.getDOM() != null) {
metadataElement = metadata.getDOM();
} else {
Marshaller marshaller =
Configuration.getMarshallerFactory().getMarshaller(metadata);
metadataElement = marshaller.marshall(metadata);
}
if (log.isDebugEnabled()) {
log.debug("Converting DOM to a string");
}
XMLHelper.writeNode(metadataElement, new FileWriter(metadataBackupFile));
So I think our marshaller isn't the culprit here, it's the XMLHelper.writeNode(), which uses a
LSSerializer. I'll investigate this some more, but it's looking like this might be an entirely DOM
level thing. Perhaps the LSSerializer can be made to not emit this namespace decl.
And I guess the stuff I discovered earlier was an entirely unrelated bug just waiting to happen...
Comment by Brent Putman [ 25/Apr/10 ]
I confirmed that the namespace decl is definitely being added by the LSSerializer in
XMLHelper.writeNode. This is the result of a simple parse with a ParserPool and then write the
DOM back out with our 2 XMLHelper methods:
writeNode:
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<md:Organization>
<md:OrganizationName xmlns:xml="http://www.w3.org/XML/1998/namespace"
xml:lang="en">Parsed University</md:OrganizationName>
</md:Organization>
</md:EntityDescriptor>
------------------------------------------prettyPrintXML:
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<md:Organization>
<md:OrganizationName xml:lang="en">Parsed University</md:OrganizationName>
</md:Organization>
</md:EntityDescriptor>
The prettyPrintXML doesn't add it, b/c it doesn't currently use LSSerializer, it instead uses a
javax.xml.transform.Transformer to output to a StreamResult. This is the reason I didn't see this
before - in my earlier test code I was using prettyPrintXML. I think this has operational issues,
b/c we often log debug/trace output with the pretty print one. I think it should be made to just do
the indenting with the Transformer (I think by using a DOMResult), but still do the actual
serialization via writeNode. That way we get consistent behavior. I'll open a new issue on that
so I don't forget.
Comment by Brent Putman [ 04/May/10 ]
Have not yet uncovered a definitive approach to make the LSSerializer behave the way we
want. I *think* the reason it is emitting the xml namespace decl is that, by default, the
LSSerializer's DOMConfiguration parameter 'namespaces' is true:
http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-namespaces
so as stated there it normalizes the namespaces according to the algorithm defined in DOM
Level 3 Core:
http://www.w3.org/TR/DOM-Level-3-Core/namespacesalgorithms.html#normalizeDocumentAlgo
which if I am reading correctly doesn't have any special exemption for Attr nodes from the xml
namespace. So by that algorithm, it would be expected that the presence of the xml:lang would
trigger the declaration. See the section of the algorithm that begins with:
// Examine and polish the attributes
//
for ( all non-namespace Attrs of Element )
Setting the 'namespaces' DOMConfiguration parameter to false does result in the the xml prefix
not being declared. I doubt this is a solution though b/c probably has other side-effects vis-a-vis
what we currently do. Would need better understanding and a lot of testing.
Setting the 'namespace-declarations' DOMConfiguration param to false also omits the xml
prefix decl. Interestingly, according to it's docs, false is supposed to "Discard all namespace
declaration attributes." However in my testing it doesn't seem to absolutely do this, the
serialized output contains for example the xmlns decl for the SAML metadata namespace.
Maybe I'm just misunderstanding it, or maybe the Xalan impl of LSSerializer is just broken. But
based on the docs, it's not what we would want in a portable solution.
Also, using the LSSerializerFilter to filter out the xml decl doesn't seem to be an option, b/c the
filter is apparently not passed namespace declaration Attr nodes, by design.
So still investigating...
Comment by Scott Cantor [ 04/May/10 ]
For context, it's worth noting that the C++ bug this was tripping is fixed, and the actual "thing
that broke" and caused us to notice it again is IE's XML parsing, which is apparently also
broken. That means there's no functional emergency to get it fixed, it's just annoying.
Comment by Chad La Joie [ 22/Jun/10 ]
I've started a thread[1] on the Xalan list (Xalan owns the serializer code) asking for a nonstandard option that could be set to suppress emitting the xml namespace decl. We'll see where
it goes.
[1] http://marc.info/?l=xalan-j-users&m=127712997110376&w=4
[JXT-45] Use Lea's concurrency annotations to indicate which classes are
thread safe and which are not Created: 11/Dec/08 Updated: 11/Dec/08
Status:
Project:
Component/s:
Fix Version/s:
Open
XMLTooling - Java
None
1.0.0, 1.0.1, 1.1.0, 1.1.1
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Improvement
Chad La Joie
Unresolved
None
Not Specified
Not Specified
Not Specified
Priority:
Assignee:
Votes:
Minor
Chad La Joie
0
[JXT-24] Suport for CDATA content. Created: 01/Aug/07
Status:
Project:
Component/s:
Fix Version/s:
Open
XMLTooling - Java
Marshalling
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Improvement
Scott Cantor
Unresolved
None
Not Specified
Priority:
Assignee:
Votes:
Updated: 31/Dec/07
Minor
Chad La Joie
0
Not Specified
Not Specified
Description
May want to see whether CDATA content can be parsed in place of regular Text nodes. Should
be a low-level change that would fix all the objects at once, but it may require tracking the
source node to properly remarshall the XML (not sure).
Comments
Comment by Scott Cantor [ 01/Aug/07 ]
FWIW, looks like c14n rules say that CDATA gets replaced by the text itself (with any
escaping), so we probably can add this feature without worrying about whether the TextContent
of an XMLObject came from CDATA or not.
Comment by Chad La Joie [ 31/Dec/07 ]
I think the code is already there. At least in Java the CDATA node is a subclass of text node and
the unmarshaller is already capturing all text nodes and sending them to be processed. Now,
whether the code handling that data does the right thing is another question. Did you see
something that made you think there was a problem?
Comment by Scott Cantor [ 31/Dec/07 ]
It may be a subclass but the Node Type is different, so if you're comparing the result of
getNodeType to the DOM constants, which is the standard way to determine the type of node,
CDATA wouldn't be handled.
I did not test it, but if you point me at the code I can look at it and tell you if it's going to work
or not.
-- Scott
[JXT-17] Need algorithm and impl for finding the entity certificate from an
unordered collection of certs which constitute a cert chain. Created: 24/May/07 Updated:
17/Sep/07
Status:
Project:
Component/s:
Fix Version/s:
Open
XMLTooling - Java
Security
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Task
Brent Putman
Unresolved
None
Not Specified
Priority:
Assignee:
Votes:
Minor
Brent Putman
0
Not Specified
Not Specified
Description
Should live in X509Util.
Primary use is to populate the entity certificate on an X509Credential, given just a bag o'certs,
e.g. from X509Data in KeyInfo.
Comments
Comment by Brent Putman [ 17/Sep/07 ]
I'm downgrading this to minor priority. The InlineX509Data KeyInfo provider was subsequently
updated
to treat the first cert in the X509Data as the entity-cert, if it can not otherwise be determined.
This is documented in the provider documentation and seems a reasonable default.
That was the only extant use case for this functionality, I think.
For the Shibboleth config use case, we explicitly
call out the entity cert with an attribute, so there's no inferring necessary.
[JXT-8] Decryption of EncryptedData that contains something other than a
single DOM Element Created: 23/May/07 Updated: 23/May/07
Status:
Project:
Component/s:
Fix Version/s:
Open
XMLTooling - Java
Encryption
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Improvement
Brent Putman
Unresolved
None
Not Specified
Priority:
Assignee:
Votes:
Minor
Brent Putman
0
Not Specified
Not Specified
Description
Apache XML Security currently only provides a "detached" XMLCipher decryption method
that returns a byte[]. The Decrypter must handle parsing this into a DocumentFragment.
Currently we only handle parsing this if it is a proper XML document instance that can be
parsed with a DocumentBuilder from our ParserPool.
One possible option is to use DOM Level 3 LSParser#parseWithContext. There is (commented
out) code in the Decrypter to do this. Unfortunately the current Xerces implementation of
LSParser does not yet support this method.
Some possible options are:
1) wait on Xerces support in LSParser
2) request an enhancement to Apache XML Security for an XMLCipher method which returns a
DocumentFragment. The C++ version of XML Security does already do this.
3) implement our own method of parsing and returning a fragment by, for example, wraping the
returned byte[] data in a dummy element (opening and closing tags) so can be parsed by a
DocumentBuilder. There may be thorny issues here with encoding, character sets, etc. The
Apache C++ library apparently does something similar.
[JOST-148] Add a Dynamic MetadataProvider analogous to the SP's version
Created: 15/Feb/11 Updated: 20/Mar/11
Status:
Project:
Component/s:
Fix Version/s:
Open
OpenSAML 2 - Java
SAML 2
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
New Feature
Scott Cantor
Unresolved
None
Not Specified
Attachments:
Issue Links:
Priority:
Assignee:
Votes:
Minor
Scott Cantor
0
Not Specified
Not Specified
DynamicMetadataProvider.java
Dependency
has dependent SC-140 Add config tooling for Dynamic Metada...
Open
Description
The extension at http://wiki.rzg.mpg.de/RESTSSO/index.php/DynMDPro should be a good
starting point (and maybe ending point?) for adding an on-the-fly plugin that handles the MDX
query spec.
I'm filing this here for now, since the configuration classes will certainly be here. I need to
check with Chad on whether we're doing an opensaml update for this release or not, since the
metadata providers are normally there.
Comments
Comment by Rod Widdowson [ 15/Feb/11 ]
JOST 147 will need a rev to OpenSaml, and I'd like to get that in for this release. But it's not my
call...
Comment by Chad La Joie [ 15/Feb/11 ]
Yes, we'll be doing an OpenSAML minor rev in order to address JOST-147, as Rod noted. So
go ahead.
Comment by Scott Cantor [ 07/Mar/11 ]
This going to be a bigger job, since the current plugin is implementing itself by creating a
dedicated HTTPMetadataProvider instance internally for each entityID/query URL, and then
caching them all. That is, umm, suboptimal.
Comment by Scott Cantor [ 20/Mar/11 ]
Tabling this for now because of complexities in the IdP's caching of keys and the need to
implement both foreground and background thread management of the cache.
Comment by Scott Cantor [ 20/Mar/11 ]
Attaching an untested version that does only foreground management of the cache. Adding a
TimerTask to sweep for entries needing an update and then updating them would complete the
implementation.
[JOST-135] Opensaml prunes empty xml namespaces, that are required for
correct encryption Created: 14/Oct/10 Updated: 21/Oct/10
Status:
Project:
Component/s:
Affects
Version/s:
Fix Version/s:
Open
OpenSAML 2 - Java
SAML 2
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Bug
kfr
Unresolved
None
Not Specified
Java Version:
Sun 1.6
None
Priority:
Assignee:
Votes:
Major
Brent Putman
0
Not Specified
Not Specified
Description
Opensaml's XML helpers prunes empty default namespaces - but according to the XML
Canoncalization ( http://www.w3.org/TR/xml-exc-c14n/ Section 3 point 4 ) it is told that:
If the token representing the default namespace is not present in InclusiveNamespaces
PrefixList, then the rules for rendering xmlns="" are changed as follows. When canonicalizing
the namespace axis of an element E that is in the node-set, output xmlns="" if and only if all of
the conditions are met:
1. E visibly utilizes the default namespace (i.e., it has no namespace prefix), and
2. it has no default namespace node in the node-set, and
3. the nearest output ancestor of E that visibly utilizes the default namespace has a default
namespace node in the node-set.
When the empty default namespace is missing then the hash value for the element which is STR
transformed is calculated incorrectly.
Comments
Comment by Brent Putman [ 14/Oct/10 ]
Can you give an example of what you are talking about here? Or a code snippet that demonstrates the problem?
I'm confused by when you say "Opensaml's XML helpers prunes empty default namespaces" and then talk about
which only comes into play practically speaking with XML Signatues, and that's all implemented by Apache xm
Also, in the subject, when you say "encryption", I assume you really mean XML signatures, rather than XML en
I know, c14n isn't involved at all in XML encryption.
Comment by Brent Putman [ 14/Oct/10 ]
I think I see what you mean. You're probably referring to this code in org.opensaml.xml.util.XMLHelper which
declaration of xmlns="" :
public static void appendNamespaceDeclaration(Element domElement, String namespaceURI, String prefix) {
String nsURI = DatatypeHelper.safeTrimOrNullString(namespaceURI);
String nsPrefix = DatatypeHelper.safeTrimOrNullString(prefix);
// This results in xmlns="" being emitted, which seems wrong.
if (nsURI == null && nsPrefix == null) {
return;
}
<snip>
As far as I know, declaring and using xmlns="" is legal, albeit uncommon with respect to our library. I didn't wri
however, so I don't know if the issue was more complicated than that.
Chad, any recollection on this?
Scott, do you support this in C++?
Simply omitting that code does allow the xmlns="" to be correctly marshalled to DOM and serialized. It's possib
be code elsewhere that has problems if the namespace URI is empty or null, though, would have to check that m
Comment by Brent Putman [ 14/Oct/10 ]
Correction, I did add that null check, in r508. Had something to do with handling the odd SOAP 1.1 fault elemen
namespace qualified. In hindsight this "fix" doesn't seem right. Will have to re-examine.
Comment by Scott Cantor [ 14/Oct/10 ]
I don't know if the C++ code handles an *empty* namespace. I don't actually know the legalities of that. Mixing
unqualified XML seems iffy.
Comment by Scott Cantor [ 14/Oct/10 ]
I forgot about the SOAP case, local elements in badly written schemas are definitely an area where you'd run int
XML.
Comment by Scott Cantor [ 14/Oct/10 ]
FWIW, I do have comments in the marshaller noting that a NULL namespace URI is considered the "empty" nam
there's no special code that would block outputting that declaration. Presumably only if it were needed, since the
is empty initially anyway.
Comment by Brent Putman [ 14/Oct/10 ]
My understanding was that this is not unqualified XML, but rather qualified, where the namespace URI is empty
sure is legal) and it happens to be assigned to the default prefix. I've always understood that to be a different case
but this is where things start to get fuzzy for me, on the edges of XML land. I guess I need to look at the Namesp
again.
Also, removing that check still results in those fault* elements correctly marshalled, so this check may not even
OTOH, another test shows that building an XMLObject with a builder using the default empty namespace result
all (completely unqualified element), so that's probably not right. :-( Probably got other edge case issues around
and/or prefixes.
Comment by Scott Cantor [ 14/Oct/10 ]
The terminology I'm familiar with, now that I'm reminded of all this, is that whenever XML is namespace-aware
"unqualified" just means "in the empty namespace". The prefix is basically orthogonal, that's just how you encod
(or lack thereof by setting the prefix, if any, to "").
I think your test is probably fine. If you marshall something that's unqualified with no parent to override anythin
namespace *is* empty, and you'd need no declaration.
Comment by Brent Putman [ 14/Oct/10 ]
So I guess you're saying that these are semantically equivalent XML, assuming that the environment is namespa
<Foo />
<Foo xmlns="" />
But what about something like:
<test:Foo xmlns:test="" />
That element is in the empty namespace, but seems wrong to say that it is "unqualified"....
Another wrinkle that I discovered impl-wise is that Java's QName class will not report a null namespace URI (vs
you use the localname-only constructor, or explicitly pass a null URI, the URI that's returned from the instance i
null empty string. So it would be very hard to make this distinction in our code, since we pas QNames around ev
represent things.
Comment by Brent Putman [ 14/Oct/10 ]
Oh, and this implies that the odd SOAP 1.1 fault elements would be correctly represented by for example:
<faultstring xmlns="" />
Not that we'd want to do that, just clarifying.
Comment by Scott Cantor [ 14/Oct/10 ]
Yes, all that is correct (and the point is that the term "qualified" is referring to the namespace, not the prefix).
Regarding the QName class, I don't follow. QNames are always namespace-aware (that's their whole origin), so
same. The localname-only constructor is just implying the empty namespace, I assume.
Speaking to that example, the reason you could need that form would be this:
<S:Envelope xmlns:S="..." xmlns="something for no apparent reason">
...
<faultstring xmlns=""/>
...
</S:Envelope>
Without the xmlns="" declaration, the element would be in that other namespace.
Comment by kfr [ 15/Oct/10 ]
Sorry for mixing encryption and signing terms
This example will show exactly what the problem is:
First a saml assertion without the default xml namespace:
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_e437ead4-b21d-407c-b0b0-e62c99d12ac2" IssueInstant="2010-09-13T12:33:40.113Z"
Version="2.0">
<saml2:Issuer>https://sts.oiosaml.net</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
Id="_1c753ae0-5703-4ff8-89e6-07d0370c6f8c">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationM
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#_e437ead4-b21d-407c-b0b0-e62c99d12ac2">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>5lQFzX4+c9o5rAoxc7g3e/EaNis=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>CHvTdTpSuEiD5FoO8ce9yR2VXZe2THTwbQFjXMOByb7GwRjXlYDvAKMLnumYLw
RJht5adQpM1L6Wy+A6CAlYrdGH7K4XPruSeD9CUl6x2tdLYo0yhbaKjaP1NrQ6YrB2/iPFbBHLlt
nX6L0fIGMC4B+ZQ5+hI=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIE/jC... (truncated)</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
... (truncated)
The an example including the empty xml namespace:
<saml2:Assertion xmlns=""
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_e437ead4-b21d-407c-b0b0-e62c99d12ac2"
IssueInstant="2010-09-13T12:33:40.113Z" Version="2.0">
<saml2:Issuer>https://sts.oiosaml.net</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
Id="_1c753ae0-5703-4ff8-89e6-07d0370c6f8c">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationM
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#_e437ead4-b21d-407c-b0b0-e62c99d12ac2">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>5lQFzX4+c9o5rAoxc7g3e/EaNis=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>CHvTdTpSuEiD5FoO8ce9yR2VXZe2THTwbQFjXMOByb7GwRjXlYDvAKMLnumYLw
RJht5adQpM1L6Wy+A6CAlYrdGH7K4XPruSeD9CUl6x2tdLYo0yhbaKjaP1NrQ6YrB2/iPFbBHLlt
nX6L0fIGMC4B+ZQ5+hI=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIE/jC... (truncated</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
... (truncated)
As you see the digestvalues are different, the specification (as mentioned in the initial post) tells that the second
correct one. The problem is that opensaml prunes that empty xml namespace - so the digestvalue is calculated w
Comment by Scott Cantor [ 15/Oct/10 ]
Your example appears to be one in which exclusive c14n would direct one to omit the namespace. So it shouldn'
begin with, whether it's in the document or not, and it wouldn't matter what the serializer did.
Comment by kfr [ 19/Oct/10 ]
I see - just to point this out
In the example above there is no InclusiveNamespaces Prefix list so the conditions from 1 to 3 (From the c14n s
must be met so the default xml namespace xmlns="" are outputted.
E which in this case is the Assertion node has a namespace prefix (saml2) - so it should not output the empty def
(xmlns="") the 2nd and 3rd condition doesn't matter since they are "AND" conditions.
The funny thing is that this conflicts with the SOAP Message Security specification (http://docs.oasis-open.org/w
spec-errata-os-SOAPMessageSecurity.pdf) section 8.3, where a not is stating the following:
Note: A namespace declaration xmlns="" MUST be emitted with every apex element that has no namespace nod
for the default namespace; cf. XML Decryption Transform.
So in this case it seems that the problem with opensaml XMLTooling is ignoring empty default xml namespaces
because of the exclusive C14N
Is that correctly understood?
Comment by Scott Cantor [ 19/Oct/10 ]
There's no conflict, that's referring to the STR transform, which is something that would be implemented separat
c14n step. I don't know why they have that requirement, or how it would impact things, but at the time you perfo
are explicit about whether the namespace would be emitted or not, regardless of whether it's present in the origin
I think Brent still feels there's a potential bug, but no, it isn't a bug in the specific case you're asking about if excl
Comment by Thomas Gundel [ 20/Oct/10 ]
Hi, allow me to step into this discussion - I am working with Kjeld on this issue.
First note that our problem is related to including an Assertion in the SOAP message signature via the STR trans
about the Assertion's own/internal signature.
As I read WSS Security 1.1 lines 1376 ff. you need to augment the canonicalization method and emit the empty
declaration during STR transform - even though the underlying canonicalization method would not emit it itself.
correct interpretation, then it would seem there is a bug in the STR Transform implementation.
---- quote from the WSS spec:
Finally, employ the canonicalization method specified as a parameter to the transform to serialize N to produce t
output of this transform; but, in place of any dereferenced <wsse:SecurityTokenReference> element Ri and its d
process the dereferenced node set Ri' instead.
During this step, canonicalization of the replacement node set MUST be augmented as follows:
o Note: A namespace declaration xmlns="" MUST be emitted with every apex element that has no namespace no
value for the default namespace; cf. XML Decryption Transform.
--- end quote
We are in a position where another implementation rejects the signature on the Asertion if the empty namespace
emitted, since the hash value is different.
Comment by Thomas Gundel [ 20/Oct/10 ]
To make the above clearer:
I think the core issue is whether the empty namespace declaration mentioned in the WSS spec is to be added bef
canonicalization or during/after such that it ends up in the octet stream which the hash value is subsequently com
If it is added before, then if exclusive canonicalization is used, it would remove it again and it has no effect.
Comment by Scott Cantor [ 20/Oct/10 ]
It doesn't matter when it's added, it will never be in the hash unless the default namespace is set to something els
it's visibly used. If it's in your hash in the example posted above, your hash is wrong, that's what I'm trying to say
not seeing something. (Of course adding #default to the inclusive list would change that.)
Comment by Thomas Gundel [ 21/Oct/10 ]
Scott, our problem is that the signature on the SOAP request generated by Opensaml is rejected by another imple
Datapower appliance) because of incorrect hash value in the message signature. If we modify the request such th
Assertion contains the empty namespace declaration (xmlns=""), the request is accepted.
We have been in contact with IBM and they pointed us to the above quoted line 1381 in the WS Security 1.1 spe
to include the empty namespace.
Comment by Scott Cantor [ 21/Oct/10 ]
I think the confusion here is over the difference between c14n and serialization. We thought you meant that the s
considered invalid. What you seem to be talking about is a serialization requirement from a different layer of sof
very different issue, and has nothing to do with the title of the bug. I think Brent was going to look into letting th
that namespace instead of suppressing it, since that is generally not the right behavior.
Comment by Brent Putman [ 21/Oct/10 ]
Yes, I personally was definitely confused by what layer of software was really at issue here (OpenSAML itself v
Apache xmlsec library). We don't handle the actual c14n op in OpenSAML code, that's in Apache xmlsec. If the
output stream over which our signature hash is calculated differs from the validating side, I don't think that's an i
OpenSAML per se. It's either a c14n bug in Apache xmlsec or on the other side (IBM appliance). The original, m
from OpenSAML shouldn't have anything to do with the canonicalized form, as calculated by xmlsec.
What I did identify was that our helper method used in marshalling suppresses the appending of the xmlns="" as
That does not appear to be correct, and also is the wrong way to go about fixing the original problem that led to t
have removed the check. You can now force the emission of that decl by the standard mechanism of registering
decl on the desired XMLObject's NamespaceManager. Again, it's not clear to me that that has anything to do wit
report. Possibly you might need to do that as a workaround for other software problems (add xmlns="" to the As
example), but we would not automatically do that in our marshalling code.
As an aside, interestingly I discovered that Xerces serialization does in fact automatically handle the case that Sc
an unqualified element (e.g. SOAP 1.1 faultcode/faultstring etc) has an ancestor (e.g. Envelope) with a decl that
prefix to a non-empty URI, Xerces automatically emits the xmlns="" decls on the unqualified elements, in order
default prefix. I had to double-check that it wasn't our code that was doing it.
Comment by Brent Putman [ 21/Oct/10 ]
Btw, we may have some other issues with this default empty namespace case, notably in the namespace manager
methods, not 100% sure yet. I will open another issue if that is that case, and reserve this one for the original pro
[JOST-114] Allow metadata filters to completely filter out a metadata set Created:
13/May/10 Updated: 13/May/10
Status:
Project:
Component/s:
Fix Version/s:
Open
OpenSAML 2 - Java
SAML 2
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Improvement
Chad La Joie
Unresolved
None
Not Specified
Priority:
Assignee:
Votes:
Minor
Chad La Joie
0
Not Specified
Not Specified
Description
Currently, a metadata filter can not filter out the top level metadata element. Allow for a filter
which completely filters out a metadata set.
[JOST-113] Add/update wiki documentation for various topics related to SAML
extensibilty Created: 21/Apr/10 Updated: 21/Apr/10
Status:
Project:
Component/s:
Fix Version/s:
Open
OpenSAML 2 - Java
None
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Task
Brent Putman
Unresolved
None
Not Specified
Priority:
Assignee:
Votes:
Minor
Brent Putman
0
Not Specified
Not Specified
Description
The existing stuff is mostly here:
https://spaces.internet2.edu/display/OpenSAML/OSTwoUsrManJavaAnyTypes
It's outdated (mentions ElementProxy), but also horribly and incorrectly conflates the
xs:anyType ur-type and the xs:any schema wildcard concepts.
It needs to be reworked into a discussion of how OpenSAML handles various aspects of
"extensibility" in SAML, including:
* support for elements with content models that use xs:any and/or xs:anyAttribute wildcards
* support for the xs:anyType schema type
* type derivation via xsi:type
* how the XSAny provider is used for various use cases, with examples
Probably make a new page with breaks all these things out, and have the existing page redirect
to it.
[JOST-90] Implement artifact decoder and encoder Created: 26/Aug/09
Status:
Project:
Component/s:
Fix Version/s:
Open
OpenSAML 2 - Java
SAML 2
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
New Feature
Mandus Elfving
Unresolved
None
Not Specified
Attachments:
Priority:
Assignee:
Votes:
Updated: 26/Mar/10
Major
Chad La Joie
0
Not Specified
Not Specified
artifact_decode.zip
artifact_decode.zip
artifact_decode.zip
Description
Add support for artifact decoding and encoding in the SAML 2 implementation.
Comments
Comment by Mandus Elfving [ 26/Aug/09 ]
Supplied is an artifact decoder, HttpArtifactDecoder, for decoding SAML artifact responses and
requesting the SAML response over a backchannel. Included is also code for setting up the
HTTPClient used for requesting the SAML Response over the backchannel.
Comment by Mandus Elfving [ 15/Mar/10 ]
Attached is a slightly rewritten version of HTTPArtifactDecoder.java (and supporting files)
removing some bloat that was there in the earlier version as well as making it conform to the
SAML specification.
Would be great if someone could looks this over and add it to the code base!
Comment by Mandus Elfving [ 26/Mar/10 ]
Fixed some bugs and added unit test for HTTPArtifactDecoder.
[JOST-10] Provide EntityDescriptor iterator on metadata provider Created:
08/Jun/07 Updated: 17/Sep/07
Status:
Project:
Component/s:
Fix Version/s:
Open
OpenSAML 2 - Java
SAML 2
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Improvement
Brent Putman
Unresolved
None
Not Specified
Issue Links:
Dependency
has dependent JOST-9 Resolver for attempting to infer SAML...
Priority:
Assignee:
Votes:
Minor
Brent Putman
0
Not Specified
Not Specified
Open
Description
Iterator should allow visiting all the EntityDescriptor elements managed by a metadata
provider.
Comments
Comment by Brent Putman [ 17/Sep/07 ]
Think we agreed to defer this until post-2.0.
Note we don't actually need to modify the metadata providers or change their API to do this.
Since we can get the XMLObject that is the root of the metadata tree, via
MetadataProvider#getMetadata,
we can do a separate Iterator/Iterable pair which takes an XMLObject on construction and walks
the tree.
This could easily (and probably should) be made more general than just metadata,
allowing general lazy traversing of a tree of XMLObjects. Possible options:
1) order of traversal - pre-order, in-order, post-order
2) callback handlers based on the name/type of current XMLObject, i.e. just return it
for the metadata case if an EntityDescriptor, or evaluate it, analyze it, etc for other
use cases.
[JOST-9] Resolver for attempting to infer SAML entity in metadata from
certificate information Created: 08/Jun/07 Updated: 17/Sep/07
Status:
Project:
Component/s:
Fix Version/s:
Open
OpenSAML 2 - Java
Security
None
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
Task
Brent Putman
Unresolved
None
Not Specified
Issue Links:
Dependency
depends on
JOST-10 Provide EntityDescriptor iterator on ...
has dependent JOST-6 Security policy rule implementations
Priority:
Assignee:
Votes:
Minor
Brent Putman
0
Not Specified
Not Specified
Open
Closed
Description
For use in security policy rules.
Comments
Comment by Brent Putman [ 17/Sep/07 ]
Think we agreed to defer this until post-2.0.
For SAML 2.0 standard profiles, Issuer is mandatory, so this is less of a priority. Maybe useful
for new
profiles which don't make Issuer mandatory.
For SAML 1.x, this is more of a concern. For Shibboleth, though, it's basically addressed
by the Shibboleth profile for the only extant problematic case, AttributeQuery.
So this has lower priority than originally thought. But will be nice to have in the future.
Generated at Fri Jul 28 20:21:15 UTC 2017 using JIRA 7.2.6#72008sha1:26175bf5a1a24af841485172355360565636e05b.
© Copyright 2026 Paperzz