How to: Use Message Security with the WCF Exchange Server Mail Transport
This example shows how to use SOAP message security with the Windows Communication Foundation (WCF) Exchange Server mail transport.
Example
The following example runs on the desktop and shows how to send and receive a message by using message security.
This example assumes that a certificate from a trusted source is present in the certificate store, and that references to the certificate in the code have been updated appropriately.
When you create a message, you must serialize the message in the CreateMessage call by passing in a custom serializer as an extra parameter. On the desktop, you can use either a custom serializer or attributes to create serialized data. However, we recommend that you use the same serializer for both the device and the desktop.
The custom serializer is not specific to the WCF Exchange Server mail transport and is not included in this example. For an example of a custom serializer, see How to: Serialize Messages in WCF Applications.
Class Program
Private Shared ChannelName As String = "Channel1"
Private Shared ServiceEmailAddress As String = "service@fabrikam.com"
Private Shared serializer As New CFMessagingSerializer(GetType(String))
Shared Sub Main(ByVal args() As String)
Dim factory As IChannelFactory(Of IOutputChannel)
Dim output As IOutputChannel
Dim bpc As BindingParameterCollection
Dim message As Message
Dim binding As ExchangeWebServiceMailBinding
Dim clientEmailServer As New Uri("http://mail.example.com")
Dim clientEmailAddress As String = "client@example.com"
Dim password As String = "password"
binding = New ExchangeWebServiceMailBinding(clientEmailServer, New NetworkCredential(clientEmailAddress, password))
binding.Security.Mode = MailSecurityMode.Message
bpc = New BindingParameterCollection()
Dim cc As New ClientCredentials()
cc.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "example.com")
cc.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.ChainTrust
cc.ServiceCertificate.SetDefaultCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "fabrikam.com")
Dim cpr As New ChannelProtectionRequirements()
' Sign and encrypt body for *all* messages
cpr.OutgoingSignatureParts.AddParts(New MessagePartSpecification(True), "*")
cpr.IncomingSignatureParts.AddParts(New MessagePartSpecification(True), "*")
cpr.OutgoingEncryptionParts.AddParts(New MessagePartSpecification(True), "*")
cpr.IncomingEncryptionParts.AddParts(New MessagePartSpecification(True), "*")
bpc.Add(cc)
bpc.Add(cpr)
factory = binding.BuildChannelFactory(Of IOutputChannel)(bpc)
factory.Open()
Dim sendAddress As New EndpointAddress(MailUriHelper.CreateUri(ChannelName, ServiceEmailAddress), EndpointIdentity.CreateX509CertificateIdentity(cc.ServiceCertificate.DefaultCertificate))
output = factory.CreateChannel(sendAddress)
message = System.ServiceModel.Channels.Message.CreateMessage(MessageVersion.Default, "urn:Test", "Hello, World!", serializer)
output.Open()
output.Send(message)
output.Close()
factory.Close()
binding.Close()
' Receiving message on the server side
'
Dim listener As IChannelListener(Of IInputChannel)
Dim input As IInputChannel
Dim serviceEmailServer As New Uri("http://mail.fabrikam.com")
binding = New ExchangeWebServiceMailBinding(serviceEmailServer, New NetworkCredential(ServiceEmailAddress, password), MailSecurityMode.Message)
' Create credential for the listening side
Dim sc As New ServiceCredentials()
sc.ServiceCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "fabrikam.com")
sc.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None
bpc = New BindingParameterCollection()
bpc.Add(sc)
bpc.Add(cpr)
listener = binding.BuildChannelListener(Of IInputChannel)(MailUriHelper.CreateUri(ChannelName, ""))
listener.Open()
input = listener.AcceptChannel()
input.Open()
message = input.Receive()
Dim data As String = message.GetBody(Of String)(serializer)
input.Close()
listener.Close()
binding.Close()
End Sub
End Class
class Program
{
private static string ChannelName = "Channel1";
private static string ServiceEmailAddress = "service@fabrikam.com";
private static CFMessagingSerializer serializer = new CFMessagingSerializer(typeof(string));
static void Main(string[] args)
{
IChannelFactory<IOutputChannel> factory;
IOutputChannel output;
BindingParameterCollection bpc;
Message message;
ExchangeWebServiceMailBinding binding;
Uri clientEmailServer = new Uri("http://mail.example.com");
string clientEmailAddress = "client@example.com";
string password = "password";
binding = new ExchangeWebServiceMailBinding(clientEmailServer,
new NetworkCredential(clientEmailAddress, password));
binding.Security.Mode = MailSecurityMode.Message;
bpc = new BindingParameterCollection();
ClientCredentials cc = new ClientCredentials();
cc.ClientCertificate.SetCertificate(
System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser,
System.Security.Cryptography.X509Certificates.StoreName.My,
System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
"example.com");
cc.ServiceCertificate.Authentication.CertificateValidationMode =
System.ServiceModel.Security.X509CertificateValidationMode.ChainTrust;
cc.ServiceCertificate.SetDefaultCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser,
System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
"fabrikam.com");
ChannelProtectionRequirements cpr = new ChannelProtectionRequirements();
// Sign and encrypt body for *all* messages
cpr.OutgoingSignatureParts.AddParts(new MessagePartSpecification(true), "*");
cpr.IncomingSignatureParts.AddParts(new MessagePartSpecification(true), "*");
cpr.OutgoingEncryptionParts.AddParts(new MessagePartSpecification(true), "*");
cpr.IncomingEncryptionParts.AddParts(new MessagePartSpecification(true), "*");
bpc.Add(cc);
bpc.Add(cpr);
factory = binding.BuildChannelFactory<IOutputChannel>(bpc);
factory.Open();
EndpointAddress sendAddress = new EndpointAddress(MailUriHelper.CreateUri(ChannelName,
ServiceEmailAddress), EndpointIdentity.CreateX509CertificateIdentity(cc.ServiceCertificate.DefaultCertificate));
output = factory.CreateChannel(sendAddress);
message = Message.CreateMessage(MessageVersion.Default, "urn:Test", "Hello, World!", serializer);
output.Open();
output.Send(message);
output.Close();
factory.Close();
binding.Close();
// Receiving message on the server side
//
IChannelListener<IInputChannel> listener;
IInputChannel input;
Uri serviceEmailServer = new Uri("http://mail.fabrikam.com");
binding = new ExchangeWebServiceMailBinding(serviceEmailServer,
new NetworkCredential(ServiceEmailAddress, password),
MailSecurityMode.Message);
// Create credential for the listening side
ServiceCredentials sc = new ServiceCredentials();
sc.ServiceCertificate.SetCertificate(
System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser,
System.Security.Cryptography.X509Certificates.StoreName.My,
System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
"fabrikam.com");
sc.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
bpc = new BindingParameterCollection();
bpc.Add(sc);
bpc.Add(cpr);
listener = binding.BuildChannelListener<IInputChannel>(MailUriHelper.CreateUri(ChannelName, ""), bpc);
listener.Open();
input = listener.AcceptChannel();
input.Open();
message = input.Receive();
string data = message.GetBody<string>(serializer);
input.Close();
listener.Close();
binding.Close();
}
}
Compiling the Code
This example requires references to the following namespaces:
Security
For more information about security options, see WCF Exchange Server Mail Transport.
See Also
Tasks
Walkthrough: Using the WCF Exchange Server Mail Transport
Other Resources
Windows Communication Foundation (WCF) Development and the .NET Compact Framework