Listing 1

<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<soap:Header>
<wsse:Security>
<!-- security-related semantics go here -->
</wsse:Security>
</soap:Header>
<soap:Body>
...
</soap:Body>
</soap:Envelope>

Listing 2

<soap:Envelope xmlns:soap="...">
<soap:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="...">
<wsse:UsernameToken xmlns:wsu="..." wsu:Id="...">
<wsse:Username>John Doe</wsse:Username>
<wsse:Password Type="wsse:PasswordDigest">sWH/NtOHThMh...
</wsse:Password>
<wsse:Nonce>WsYRGC7Kwqz8...</wsse:Nonce>
<wsu:Created>...</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
...
</soap:Body>
</soap:Envelope>

Listing 3

<configuration> 
...
<system.web>
...
<webServices>
<soapExtensionTypes>
<add type="Microsoft.Web.Services.WebServicesExtension,
Microsoft.Web.Services, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" priority="1" group="0"
/>
</soapExtensionTypes>
</webServices>
</system.web>
...
<configuration>


Listing 4

// create service proxy and obtain context
MyService proxy = new MyService();

// obtain a reference to context
SoapContext context = proxy.RequestSoapContext;

// create a UsernameToken
UsernameToken token = new UsernameToken("John", "ESS",
PasswordOption.SendHashed);

// add token to <wsse:Security> header
context.Security.Tokens.Add(token);

// invoke the service
proxy.DoSomething();


Listing 5

<soap:Envelope xmlns:soap="...">
<soap:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="...">
<wsse:UsernameToken xmlns:wsu="..."
wsu:Id="SecurityToken-5f4cf369...">
<wsse:Username>Johnny</wsse:Username>
<wsse:Password Type="wsse:PasswordDigest">zv87of42yK7i...
</wsse:Password> 
<wsse:Nonce>rBBN7O46wle5...</wsse:Nonce>
<wsu:Created>...</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<DoSomething xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope>

Listing 6

public class MyPasswordProvider : IPasswordProvider
{
public string GetPassword(UsernameToken token)
{
// validate input parameter(s)
if (token == null) throw new ArgumentNullException("token");

// obtain password (pwd) from a secure data store (i.e. database)
// ...

// authenticate identity
if (pwd != token.Password) throw new ApplicationException
("Missing or invalid credentials.");

return pwd;
}
}


Listing 7

[WebService]
public class MyService
{
[WebMethod]
public void DoSomething()
{
SoapContext requestContext = HttpSoapContext.RequestContext;
if (requestContext == null) throw new ApplicationException
("Non-SOAP request.");

if (!UsernameTokenExists(requestContext.Security))
{
// error handling
}

// at this point, we have verified the existence of a UsernameToken,
// which has been authenticated by the IPasswordProvider

// do something
}

public bool UsernameTokenExists(Security securityHeader)
{
bool usernameTokenExists = false;
if (securityHeader.Tokens.Count > 0)
{
foreach (SecurityToken securityToken in securityHeader.Tokens)
{
UsernameToken token = securityToken as UsernameToken;
if (token != null )
{
usernameTokenExists = (token.Username == null ||
token.Username == string.Empty) ? false : true;
}
}
}
return usernameTokenExists;
}
}

Listing 8

<configuration>
<configSections>
<section name="microsoft.web.services"
type="Microsoft.Web.Services.Configuration.
WebServicesConfiguration,
Microsoft.Web.Services, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
/>
</configSections>
...
<microsoft.web.services>
<security>
<passwordProvider type=" SysCon.PasswordProvider,
MyService" />
</security>
</microsoft.web.services>
...
</configuration>


Listing 9

// create service proxy and obtain context
MyService proxy = new MyService();

// obtain a reference to context
SoapContext context = proxy.RequestSoapContext;

// create a UsernameToken
UsernameToken token = new UsernameToken("John", "ESS",
PasswordOption.SendHashed);

// add token to <wsse:Security> header and sign the outbound
SOAP message body
context.Security.Tokens.Add(token);
context.Security.Elements.Add(new Signature(token));

// invoke the service
proxy.DoSomething();


Listing 10

<soap:Envelope xmlns:soap="...">
<soap:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="...">
...
<wsse:UsernameToken xmlns:wsu="..." wsu:Id="SecurityToken-441afff1...">
<wsse:Username>John</wsse:Username>
<wsse:Password Type="wsse:PasswordDigest">lLMJL9n5p+nt...
</wsse:Password>
<wsse:Nonce>GNBo5jE4ZSMX...</wsse:Nonce>
<wsu:Created>...</wsu:Created>
</wsse:UsernameToken>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" />
<Reference URI="#Id-16d9c5c8...">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>55A8rP431oVi...</DigestValue>
</Reference>
...
</SignedInfo>
<SignatureValue>kK/9ORHX7dZy...</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#SecurityToken-441afff1..." />
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</soap:Header>
<soap:Body wsu:Id="Id-16d9c5c8..." xmlns:wsu="...">
<DoSomething xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope>


Listing 11

[WebService]
public class MyService
{
[WebMethod]
public void DoSomething()
{
SoapContext requestContext = HttpSoapContext.RequestContext;
if (requestContext == null) throw new ApplicationException
("Non-SOAP request.");

if (!IsSignatureValid(requestContext.Security))
{
// error handling
}

// at this point, we have verified the existence of a
signed message body,

// do something
}

public bool IsSignatureValid (Security securityHeader)
{
bool isSignatureValid = false;
if (securityHeader.Tokens.Count > 0)
{
foreach (ISecurityElement securityElement in securityHeader.Elements)
{
Signature signature = securityElement as Signature;
if (signature != null && (signature.SignatureOptions & SignatureOptions.IncludeSoapBody) != 0)
{
UsernameToken usernameToken = signature.SecurityToken as UsernameToken;
if (usernameToken != null)
{
string username = usernameToken.Username;

// authorize usage (isAuthorized)

isSignatureValid = isAuthorized;
}
}
}
}
return isSignatureValid;
}
}


Listing 12

// create service proxy and obtain context
MyService proxy = new MyService();

// obtain a reference to context
SoapContext context = proxy.RequestSoapContext;

// obtain a reference to "My" certificate store
X509CertificateStore store = X509CertificateStore.CurrentUserStore(X509CertificateStore.MyStore);
bool open = store.OpenRead();

// verify store reference

// select the certificate of the message receiver from certificate store
X509Certificate certificate = store.FindCertificateByKeyIdentifier(keyId)[0] as X509Certificate;

// verify that the certificate supports data encryption
if (!certificate.SupportsDataEncryption)
{
// error handling
}

// establish a security token
X509SecurityToken token = new X509SecurityToken(certificate);

// add security element to encrypt the data
context.Security.Elements.Add(new EncryptedData(token));

// invoke the service
proxy.DoSomething();

Listing 13

<soap:Envelope xmlns:soap="...">
<soap:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="...">
<xenc:EncryptedKey
Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm=
"http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier ValueType="wsse:X509v3">YREtZqvvVlQG5...</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>dkOuxRj55EK1...</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#EncryptedContent-6171adbb..." />
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
</soap:Header>
<soap:Body xmlns:wsu="..." wsu:Id="Id-a4baa6a6-...">
<xenc:EncryptedData
Id="EncryptedContent-6171adbb..."
Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="...">
<xenc:EncryptionMethod Algorithm=
"http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /> 
<xenc:CipherData>
<xenc:CipherValue>ixrCkjI4jaGZ6...</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>