This documentation is archived and is not being maintained.

How to: Use Message Security with the WCF Exchange Server Mail Transport

.NET Framework 3.5

This example shows how to use SOAP message security with the Windows Communication Foundation (WCF) Exchange Server mail transport.

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 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();

    }
}

For more information about security options, see WCF Exchange Server Mail Transport.

Show: