This sample demonstrates how to use the WS2007HttpRelayBinding binding with message security to secure end-to-end messages while still requiring clients to authenticate with the Service Bus. This allows the Service Bus to control client access to the service endpoint while enabling encryption/signature protection on the message path.

Prerequisites

If you haven't already done so, read the release notes document that explains how to sign up for a Windows Azure account and how to configure your environment.

Echo Service

The service implements a simple contract with a single operation named Echo. The Echo service accepts a string and echoes it back.

C# 
[ServiceBehavior(Name = "EchoService", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]
class EchoService : IEchoContract
{
    public string Echo(string text)
    {
        Console.WriteLine("Echoing: {0}", text);
        return text;            
    }
}

The service configuration contains one endpoint that refers to a WS2007HttpRelayBinding configuration, which uses message security with no client credential. To secure the endpoint, the service is configured with the certificateServiceBehavior behavior. This behavior contains the service credentials backed by the test certificate generated and installed using the setup.bat script.

Xml 
<configuration>
  <system.serviceModel>
    
    <behaviors>    
      <endpointBehaviors>
        <behavior name="sharedSecretClientCredentials">
          <transportClientEndpointBehavior credentialType="SharedSecret">
            <clientCredentials>
              <sharedSecret issuerName="ISSUER_NAME" issuerSecret="ISSUER_SECRET" />
            </clientCredentials>
          </transportClientEndpointBehavior>
        </behavior>
      </endpointBehaviors>

      <serviceBehaviors>
        <behavior name="certificateServiceBehavior">
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>  
    </behaviors>
    
    <bindings>
      <!-- Application Binding -->
      <ws2007HttpRelayBinding>
        <binding name="messageSecurity">
          <security mode="Message">
            <message clientCredentialType="None"/>
          </security>
        </binding>
      </ws2007HttpRelayBinding>
    </bindings>

    <services>
      <!-- Application Service -->
      <service name="Microsoft.ServiceBus.Samples.EchoService" behaviorConfiguration="certificateServiceBehavior">
        <endpoint name="ServiceBusEndpoint"
                  contract="Microsoft.ServiceBus.Samples.IEchoContract"
                  binding="ws2007HttpRelayBinding"
                  bindingConfiguration="messageSecurity"
                  behaviorConfiguration="sharedSecretClientCredentials" />
      </service>
    </services>

  </system.serviceModel>
</configuration>

Echo Service Client

The client is very similar to the client in the Echo sample, but differs in configuration and in how the channel factory is configured.

C# 
ChannelFactory<IEchoChannel> channelFactory = new ChannelFactory<IEchoChannel>("ServiceBusEndpoint", new EndpointAddress(serviceUri, EndpointIdentity.CreateDnsIdentity("localhost")));

Note that the ChannelFactory is constructed using an EndpointAddress that has an explicit "DNS" EndpointIdentity. The terminology may be a bit misleading here, because the identity is not directly related to DNS but rather to the certificate subject name. The identity name (localhost in this case) refers directly to the subject name of the certificate that is specified for the service identity in the certificateServiceBehavior behavior on the service-side. For an actual implementation, the service identity should be backed by a production certificate issued by a trusted CA and the EndpointIdentity must refer to its subject name.

The client configuration mirrors the service configuration with a few exceptions. The client endpoints are configured with the certificateEndpointBehavior behavior, with <clientCredentials> settings that turn off certificate validation specifically for the test certificate that is being used here. For an actual implementation that uses a CA issued certificate, you should omit this override.

Xml 
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="certificateEndpointBehavior">
          <clientCredentials>
            <serviceCertificate>
              <!-- The sample sets certificateValidationMode to None because it uses self-issued certificates.
                   Applications should typically set this value to ChainTrust (the default) or Custom if a customCertificateValidator is
                   specified. -->
              <authentication certificateValidationMode="None" />
            </serviceCertificate>
          </clientCredentials>
          <transportClientEndpointBehavior credentialType="SharedSecret">
            <clientCredentials>
              <sharedSecret issuerName="ISSUER_NAME" issuerSecret="ISSUER_SECRET" />
            </clientCredentials>
          </transportClientEndpointBehavior>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    
    <bindings>
      <!-- Application Binding -->
      <ws2007HttpRelayBinding>
        <binding name="messageSecurity">
          <security mode="Message">
            <message clientCredentialType="None"/>
          </security>
        </binding>
      </ws2007HttpRelayBinding>
    </bindings>

    <client>
      <!-- Application Endpoint -->
      <endpoint name="ServiceBusEndpoint"
                contract="Microsoft.ServiceBus.Samples.IEchoContract"
                binding="ws2007HttpRelayBinding"
                bindingConfiguration="messageSecurity"
                behaviorConfiguration="certificateEndpointBehavior" />
    </client>
  </system.serviceModel>
</configuration>

Running the Sample

To run the sample, first open App.config in both Serivce and Client projects and replace the place-holders ISSUER_NAME and ISSUER_SECRET with the issuer name and secret you want to use.
Note that you may use the same values in both projects or alternately, you can set up multiple issuers and use different values for the Service and Client.

To generate and install the self-issued cerificate used by the sample, run the setup.bat file included in the sample solution from a Visual Studio command line window running with Administrator privileges.

After updating the configuration files, build the solution in Visual Studio 2010 or from the command line, then run the two resulting executables. Start the service first using an elevated command prompt, then run the client. Both programs start by prompting you to type your service namespace.

When the service and the client are running, you can start typing messages into the client application. These messages are echoed by the service.

After stopping the client and service you can run cleanup.bat from a Visual Studio command line window with Administrator privileges to remove the sample certificate from your computer's local store.

Expected Output – Client

Your Service Namespace: <service namespace> 
Enter text to echo (or [Enter] to exit): Hello, World!
Server echoed: Hello, World!

Expected Output – Service

Service address: https://<service namespace>.servicebus.windows.net/EchoService/
Press [Enter] to exit
Echoing: Hello, World!


Did you find this information useful? Please send your suggestions and comments about the documentation.