This sample demonstrates using the NetTcpRelayBinding binding with message security.
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.
Before running the sample, you must run the Setup.bat script from the solution directory in a Visual Studio 2010 (or above) or a Windows SDK command prompt running with administrator privileges. The setup script creates and installs an X.509 test certificate that is used as the service identity. After running the sample, you should run the Cleanup.bat script to remove the certificate.
The service implements a simple contract with a single operation named Echo. The Echo service accepts a string and echoes the string 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 active and two additional
optional service settings. The default endpoint configuration refers to a
NetTcpRelayBinding binding configuration that uses a
UserName
credential for message security. The alternate
relayClientAuthenticationNone
configuration refers to a
NetTcpRelayBinding binding configuration that uses a
UserName
credential for message security, and also disables the
relay client authentication. The second alternate configuration,
transportWithMessageCredential
, uses a message credential for
end-to-end authentication/authorization, but relies on SSL for message
protection.
To secure the endpoint, the service is configured with the
usernamePasswordServiceBehavior
behavior. This behavior contains
the service credentials (backed by the test certificate generated and installed
by the Setup.bat script) and refers to the
SimpleUserNamePasswordValidator
in the service project that
authenticates the credentials. This validator recognizes two hard-coded username and password combinations: test1/1tset and test2/2tset. Refer to the
WCF Authentication documentation section for information about implementing other
credential validators.
Xml | |
---|---|
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="usernamePasswordServiceBehavior"> <serviceCredentials> <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" /> <userNameAuthentication userNamePasswordValidationMode="Custom" includeWindowsGroups="false" customUserNamePasswordValidatorType="Microsoft.ServiceBus.Samples.SimpleUsernamePasswordValidator, NetTcpRelayMsgSecUserNameService" /> </serviceCredentials> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="sharedSecretEndpointBehavior"> <transportClientEndpointBehavior credentialType="SharedSecret"> <clientCredentials> <sharedSecret issuerName="ISSUER_NAME" issuerSecret="ISSUER_SECRET" /> </clientCredentials> </transportClientEndpointBehavior> </behavior> </endpointBehaviors> </behaviors> <bindings> <netTcpRelayBinding> <!-- Default Binding Configuration--> <binding name="default"> <security mode="Message"> <message clientCredentialType="UserName"/> </security> </binding> <!-- Alternate Binding Configuration #1: Disabling Client Relay Authentication --> <binding name="relayClientAuthenticationNone"> <security mode="Message" relayClientAuthenticationType="None"> <message clientCredentialType="UserName"/> </security> </binding> <!-- Alternate Binding Configuration #2: Transport With Message Credential --> <binding name="transportWithMessageCredential"> <security mode="TransportWithMessageCredential"> <message clientCredentialType="UserName"/> </security> </binding> </netTcpRelayBinding> </bindings> |
The client is similar to the Echo sample client, but differs in configuration and how the channel factory is configured with the correct end-to-end credentials.
C# | |
---|---|
ChannelFactory<IEchoChannel> channelFactory = new ChannelFactory<IEchoChannel>("RelayEndpoint", new EndpointAddress(serviceUri, EndpointIdentity.CreateDnsIdentity("localhost"))); channelFactory.Credentials.UserName.UserName = "test1"; channelFactory.Credentials.UserName.Password = "1tset"; |
Note that the ChannelFactory
is constructed using an
EndpointAddress
that has an explicit DNS
EndpointIdentity
. However, 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 usernamePasswordServiceBehavior
behavior in
the service. For an actual implementation, the service identity should be
backed by a production certificate issued by a trusted certificate authority
(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
usernamePasswordEndpointBehavior
behavior with
<clientCredentials>
settings that disable certificate
validation specifically for the test certificate being used. For an actual
implementation that uses a CA-issued certificate, you should omit this
override.
Xml | |
---|---|
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="sharedSecretEndpointBehavior"> <transportClientEndpointBehavior credentialType="SharedSecret"> <clientCredentials> <sharedSecret issuerName="ISSUER_NAME" issuerSecret="ISSUER_SECRET" /> </clientCredentials> </transportClientEndpointBehavior> <clientCredentials> <serviceCertificate> <authentication certificateValidationMode="None" /> </serviceCertificate> </clientCredentials> </behavior> <behavior name="noCertificateValidationEndpointBehavior"> <clientCredentials> <serviceCertificate> <authentication certificateValidationMode="None" /> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <bindings> <!-- Application Binding --> <netTcpRelayBinding> <!-- Default Binding Configuration--> <binding name="default"> <security mode="Message"> <message clientCredentialType="UserName"/> </security> </binding> <!-- Alternate Binding Configuration #1: Disabling Client Relay Authentication --> <binding name="relayClientAuthenticationNone"> <security mode="Message" relayClientAuthenticationType="None"> <message clientCredentialType="UserName"/> </security> </binding> <!-- Alternate Binding Configuration #2: Transport With Message Credential --> <binding name="transportWithMessageCredential"> <security mode="TransportWithMessageCredential"> <message clientCredentialType="UserName"/> </security> </binding> </netTcpRelayBinding> </bindings> <client> <!-- Default configuration. You must comment out the following declaration whenever you want to use any of the alternate configurations below. --> <endpoint name="RelayEndpoint" contract="Microsoft.ServiceBus.Samples.IEchoContract" binding="netTcpRelayBinding" bindingConfiguration="default" behaviorConfiguration="sharedSecretEndpointBehavior" address="" /> </system.serviceModel> </configuration> |
Substitute the ISSUER_NAME and ISSUER_SECRET strings in the service and client App.config files with appropriate values.
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.
To run the sample, build the solution in Visual Studio or from the command line, then run the two resulting executables from a command prompt. Start the service first, then start the client application.
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
Enter the Service Namespace you want to connect to: <Service Namespace> Enter text to echo (or [Enter] to exit): Hello, World! Server echoed: Hello, World! |
Expected Output – Service
Enter the Service Namespace you want to connect to: <Service Namespace>
Service address: sb://<serviceNamespace>.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.
</a></P></DIV></BODY></HTML>