When you try to implement OASIS Web Services Security
(WS-Security) 1.0, you may receive a WSE590 exception in Microsoft Web Services
Enhancements 3.0 for Microsoft .NET (WSE).
This problem occurs when the
SecurityTokenReference class does not contain a
KeyIdentifier element. Instead, the security token reference relies on the
<ds:X509SerialNumber> digital signature element to identify the certificate. However,
WSE 3.0 does not correctly parse the value of the
<ds:X509SerialNumber> digital signature element.
To work around this problem, create and add a
KeyIdentifier element to match the key that is used to sign the original
message. You have to override the
ProcessMessage method to modify the
EncryptedKey element that identifies the subnode of the
KeyInfo element. Then you have to remove the subnode of the
KeyInfo element.
Microsoft provides programming examples for illustration only,
without warranty either expressed or implied. This includes, but is not limited
to, the implied warranties of merchantability or fitness for a particular
purpose. This article assumes that you are familiar with the programming
language that is being demonstrated and with the tools that are used to create
and to debug procedures. Microsoft support engineers can help explain the
functionality of a particular procedure, but they will not modify these
examples to provide added functionality or construct procedures to meet your
specific requirements.
The following XML code sample adds a
KeyIdentifier element to the node of the
EncryptedKey element.
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-.0#Base64Binary">MIGfMa0GCSq</wsse:KeyIdentifier>
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>OU=Secure Server Certification Authority, O="RSA Data
Security, Inc.", C=US</ds:X509IssuerName>
<ds:X509SerialNumber>51387446156789182432449128610772276634</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</EncryptedKey>
The following sample application shows how to override the
ProcessMessage method of the
SoapFilter class.
public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
{
XmlNamespaceManager nsmanager = new
XmlNamespaceManager(envelope.NameTable);
nsmanager.AddNamespace("wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")
;
nsmanager.AddNamespace("soapenv",
"http://schemas.xmlsoap.org/soap/envelope");
nsmanager.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
nsmanager.AddNamespace("soapenc",
"http://schemas.xmlsoap.org/soap/encoding");
nsmanager.AddNamespace("e", "http://www.w3.org/2001/04/xmlenc#");
try
{
XmlNodeList KeyInfoNodeList =
envelope.SelectNodes("/soapenv:Envelope/soapenv:Header/wsse:Security/e:EncryptedKey/
ds:KeyInfo", nsmanager);
XmlNodeList SecurityTokenReferenceNodeList =
KeyInfoNodeList[0].SelectNodes("wsse:SecurityTokenReference", nsmanager);
XmlNodeList EncryptedKeyNodeList =
envelope.SelectNodes("/soapenv:Envelope/soapenv:Header/wsse:Security/e:EncryptedKey"
, nsmanager);
SecurityTokenReference mySecurityTokenReference = new
SecurityTokenReference((XmlElement)SecurityTokenReferenceNodeList[0]);
KeyIdentifier myKeyIdentifier = new KeyIdentifier("MIGfMa0GCSq");
mySecurityTokenReference.KeyIdentifier = myKeyIdentifier;
KeyInfoNodeList[0].RemoveAll();
KeyInfoNodeList[0].AppendChild(mySecurityTokenReference.GetXml(envelope));
EncryptedKey key = new
EncryptedKey((XmlElement)EncryptedKeyNodeList[0]);
EncryptedKeyToken key2 = new
EncryptedKeyToken((XmlElement)EncryptedKeyNodeList[0]);
EncryptedKeyTokenManager manager = new
EncryptedKeyTokenManager();
manager.VerifyToken(key2);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
return base.ProcessMessage(envelope);
} When the application overrides the
ProcessMessage method in a derived class, the application processes the message
that is contained in a SOAP envelope. The
ProcessMessage method returns the value of the
SoapFilterResult class. This class determines whether to continue to process the
message to the next SOAP filter in the pipeline or to exit the
process.
Microsoft
has confirmed that this is a problem in the Microsoft products that are listed
in the "Applies to" section.
For more information about the set of core classes that are
used in WSE-enabled applications, visit the following Microsoft Developer
Network (MSDN) Web site:
For more information about the set of core classes that help
secure SOAP messages, visit the following MSDN Web site:
For more information about XML Digital Signature, visit the
following MSDN Web site:
The
third-party products that this article discusses are manufactured by companies
that are independent of Microsoft. Microsoft makes no warranty, implied or
otherwise, regarding the performance or reliability of these products.