Wil,
Thanks. Reviewing my message, I figured out I left out the most important
part, namely the signing and encrypting. (that happens when you snip a code
sample, I guess).
I think your example is good, but I would like to note two things:
A)
Microsoft recommends that you use a derived token to encrypt and sign,
rather than the X509 certificate itself. (I don't believe it applies to
UsernameTokens, at least, it doesn't work for me with UsernameTokens)
B)
I would not put the responsibility of encrypting (or even create the
envelope itself) in the client. The reason you are creating a proxy
(MySoapClient class in your case, SoapProxy in my case) is to encapsulate
that functionality. Otherwise, there is no reason at all to inherit
SoapClient.
HTH,

Signature
Sven
> SA,
>
[quoted text clipped - 44 lines]
> >
> > HTH,
----------------------------------------------------------------------------
----
> using System;
> using Microsoft.Web.Services2;
[quoted text clipped - 48 lines]
>
> MySoapClient client = new MySoapClient(new
Uri("http://localhost/InventoryService/InventoryService.asmx"));
> //Use the WSE X.509 Certificate Tool to look these up
> string signatureTokenBase64KeyId =
"I54aep46Cb8F0lF4YADcXBd9heI="; // private client key
> string encryptionTokenBase64KeyId =
"ONZYTaXbTLCcqdJ13eVRefII0QA="; // service public key
> X509CertificateStore store = null;
>
[quoted text clipped - 6 lines]
> // Sign the SOAP message using the private key
> store =
X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
> X509SecurityToken signatureToken =
RetrieveTokenFromStore(store, signatureTokenBase64KeyId);
> if (signatureToken == null)
> throw new ApplicationException("Unable to obtain
client security token.");
> request.Context.Security.Tokens.Add(signatureToken);
>
> //Sign only the Body portion of the envelope (optional)
> MessageSignature signature = new MessageSignature(
signatureToken );
> signature.SignatureOptions =
SignatureOptions.IncludeSoapBody;
> request.Context.Security.Elements.Add(signature);
> }
[quoted text clipped - 3 lines]
> // Encrypt the soap message using the service's public key
> store =
X509CertificateStore.LocalMachineStore(X509CertificateStore.TrustStore);
> X509SecurityToken encryptionToken =
RetrieveTokenFromStore(store, encryptionTokenBase64KeyId);
> if (encryptionToken == null)
> throw new ApplicationException("Unable to obtain
service security token.");
> request.Context.Security.Elements.Add(new
EncryptedData(encryptionToken));
> request.Context.Security.Timestamp.TtlInSeconds = 60;
> }
>
> //populate the body of the SOAP message
> System.Xml.XmlElement body = request.CreateBody();
> body.InnerXml = "<InventoryRequest
xmlns=\"Vendor.WebService/Inventory\">"
> + "<Widgets>"
> + "<Widget DeptId=\"1\">Hammer</Widget> "
[quoted text clipped - 14 lines]
> //Right out of WSE 2.0 Quickstarts example applications
> private static X509SecurityToken
RetrieveTokenFromStore(X509CertificateStore store, string keyIdentifier)
> {
> if ( store == null )
[quoted text clipped - 7 lines]
> {
> X509CertificateCollection certs =
store.FindCertificateByKeyIdentifier( Convert.FromBase64String(
keyIdentifier ) );
> if (certs.Count > 0)
> {
> token = new X509SecurityToken( ((X509Certificate)
certs[0]) );
> }
> }
[quoted text clipped - 9 lines]
> }
> }