How to: Encrypt a SOAP Message by Using a User Name and Password
The following procedures detail how to use code to encrypt a SOAP message by using a user name and password.
Note
The UsernameToken security token should only be used to identify the client and not to digitally sign or encrypt SOAP messages. When a SOAP message is digitally signed or encrypted by using a UsernameToken security token, it is susceptible to a dictionary attack. Instead, use the UsernameToken security token for identity and an EncryptedKeyToken security token to digitally sign or encrypt the SOAP messages. The <usernameForCertificateSecurity> Element turnkey security assertion uses this model.
To use code to encrypt a SOAP message by using a user name and password
Create a custom policy assertion.
For more details about creating custom policy assertions, see How to: Create a Custom Policy Assertion that Secures SOAP Messages.
Add references to the Microsoft.Web.Services3, System.Web.Services, and System.Security assemblies.
- On the Project menu, click Add Reference.
- Click the .NET tab, select Microsoft.Web.Services3.dll, and then click Select.
- On the .NET tab, select System.Web.Services.dll, and then click Select.
- On the .NET tab, select System.Security.dll, and then click Select.
- Click OK.
In the policy assertion, override the SecureMessage method.
The following code example overrides the SecureMessage method for the client output SOAP filter.
Public Overrides Sub SecureMessage(ByVal envelope As SoapEnvelope, ByVal security As Security)
public override void SecureMessage(SoapEnvelope envelope, Security security) {
Add Imports or using directives to the top of the file that communicates with the Web service.
In Solution Explorer, right-click the file that contains the client code, and then click View Code.
At the top of the file, add the directives as shown in the following code example.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.Xml Imports System.Security.Cryptography.X509Certificates Imports Microsoft.Web.Services3 Imports Microsoft.Web.Services3.Design Imports Microsoft.Web.Services3.Security Imports Microsoft.Web.Services3.Security.Tokens
using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptography.X509Certificates; using Microsoft.Web.Services3; using Microsoft.Web.Services3.Design; using Microsoft.Web.Services3.Security; using Microsoft.Web.Services3.Security.Tokens;
Within the SecureMessage method, create a new UsernameToken instance, specifying the user name, password, and how the password is sent in the SOAP message.
The Web service provides a class that derives from the UsernameTokenManager class, which includes the AuthenticateToken method. The AuthenticateToken method is given the user name in the SOAP message, but no form of the user name's password. The AuthenticateToken method is expected to return the user name's password or password equivalent. WSE calls the AuthenticateToken method, and then compares the password or password equivalent to the one that was received in the SOAP message. The following table explains the options for passing the password in the SOAP message.
PasswordOption enumeration member Description SendNone
The password is never sent in any form in the SOAP message, but WSE does use the password to sign the SOAP message. A recipient must provide a password to WSE during the signature validation stage.
SendHashed
The SHA-1 hash of the password is sent in the SOAP message. This is the best way to help protect the password. When a SOAP message is received with a UsernameToken, WSE calls the AuthenticateToken method of the class deriving from UsernameTokenManager that is registered in the configuration file. The AuthenticateToken method returns a password or password equivalent, from which WSE creates a SHA-1 hash. That SHA-1 hash is compared to the one in the SOAP message and if they are identical, the hashed password is deemed valid.
SendPlainText
The password is always sent in plain text in the SOAP message. This option is recommended only when the UsernameToken is encrypted using a security token or certificate that was obtained from the target Web service or SSL, or when a similar protocol is used to connect to the Web service; otherwise, the password could be intercepted. When WSE is running on the recipient's computer, it compares the plain text password or password equivalent in the SOAP message to the one that is returned from the AuthenticateToken method of the class deriving from UsernameTokenManager. If they are identical, the password is deemed valid.
The following code example does not send the password in plain text.
Dim userToken As UsernameToken = _ New UsernameToken(userName, passwordEquivalent, _ PasswordOption.SendNone)
UsernameToken userToken = new UsernameToken(userName, passwordEquivalent, PasswordOption.SendPlainText);
Add the UsernameToken to the WS-Security SOAP header.
' Add the token to the WS-Security header. security.Tokens.Add(userToken)
// Add the token to the WS-Security header. security.Tokens.Add(userToken);
Encrypt the SOAP message by creating a new instance of the EncryptedData class using the UsernameToken just added to the WS-Security SOAP header.
' Encrypt the SOAP request by using a user name and password. security.Elements.Add(New EncryptedData(userToken))
// Encrypt the SOAP request by using a user name and password. security.Elements.Add( new EncryptedData(userToken));
Example
The following code example creates a UsernameToken security token, and then encrypts a SOAP request by using the token.
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Xml
Imports System.Security.Cryptography.X509Certificates
Imports Microsoft.Web.Services3
Imports Microsoft.Web.Services3.Design
Imports Microsoft.Web.Services3.Security
Imports Microsoft.Web.Services3.Security.Tokens
...
Public Overrides Sub SecureMessage(ByVal envelope As SoapEnvelope, ByVal security As Security)
Dim userToken As UsernameToken = _
New UsernameToken(userName, passwordEquivalent, _
PasswordOption.SendNone)
' Add the token to the WS-Security header.
security.Tokens.Add(userToken)
' Encrypt the SOAP request by using a user name and password.
security.Elements.Add(New EncryptedData(userToken))
End Sub
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Design;
using Microsoft.Web.Services3.Security;
using Microsoft.Web.Services3.Security.Tokens;
...
public override void SecureMessage(SoapEnvelope envelope, Security security)
{
UsernameToken userToken = new UsernameToken(userName, passwordEquivalent,
PasswordOption.SendPlainText);
// Add the token to the WS-Security header.
security.Tokens.Add(userToken);
// Encrypt the SOAP request by using a user name and password.
security.Elements.Add(
new EncryptedData(userToken));
}
See Also
Tasks
How to: Verify Digital Signatures of SOAP Messages Signed Using a User Name and Password
How to: Encrypt a SOAP Message