Skip to content

Latest commit

 

History

History
 
 

RelayHttp

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Azure Service Bus Relay HTTP Sample

This sample shows how to create and run a simple ("REST") relayed HTTP(S) service with minimal ceremony.

It also demonstrates the Relay's load balancing capabilities.

Prerequisites and Setup

All samples share the same basic setup, explained in the main README file. There are no extra setup steps for this sample. The application entry points are in Main.cs, which is shared across all samples. The sample implementations generally reside in Program.cs, starting with Run().

You can build the sample from the command line with the build.bat or build.ps1 scripts. This assumes that you have the .NET Build tools in the path. You can also open up the RelayTcp.sln solution file with Visual Studio and build. With either option, the NuGet package manager should download and install the WindowsAzure.ServiceBus package containing the Microsoft.ServiceBus.dll assembly, including dependencies.

##Service

The service implementation is in a single file Program.cs and implements a minimal Windows Communication Foundation (WCF) HTTP web service.

The host is creates as a WebServiceHost, which takes care of all the right incantations for a WCF web service to function. Instead of the stock WCF WebHttpBinding, this sample uses the WebHttpRelayBinding that comes with the Service Bus client assembly.

We configure the binding with the EndToEndWebHttpSecurityMode.Transport option, which enforces the use of HTTPS (with SSL/TLS over port 443) by the client, meaning HTTP access (port 80) will not be available on the Relay endpoint.

We also define the RelayClientAuthenticationType.RelayAccessToken option, which is also the default choice when omitted, enforcing that all clients must bring a valid token with "Send" permission for the endpoint in their HTTPS requests to the Service Bus hosted endpoint.

using (var host = new WebServiceHost(this.GetType()))
{
    var webHttpRelayBinding = new WebHttpRelayBinding(EndToEndWebHttpSecurityMode.Transport,
                                                        RelayClientAuthenticationType.RelayAccessToken)
                                                        {IsDynamic = false};
    host.AddServiceEndpoint(this.GetType(),
        webHttpRelayBinding,
        httpAddress)
        .EndpointBehaviors.Add(
            new TransportClientEndpointBehavior(
                TokenProvider.CreateSharedAccessSignatureTokenProvider(listenToken)));

The web service is a simple GET on the sub-path './Image' that returns a JPEG image

        [OperationContract, WebGet]
        Stream Image()
        {
            var stream = new MemoryStream();
            SampleImage.Save(stream, ImageFormat.Jpeg);
            stream.Position = 0;
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
            return stream;
        }

##Client

Since using a plain browser client would throw us a little off track for a C# sample due to the access control token requirement and the required JavaScript mechanics, this starter sample comes with a minimal Windows Forms client.

When loading, the Windows Forms client calls the web service, retrieves the image and displays it.

The only "special" code here is the addition of a header into the HTTP request that contains the supplied SAS token. Service Bus understands (and strips!) either the Authorization header or the ServiceBusAuthorization header. If the latter is present, the Authorization header remains uninspected and untouched.

The token that is targeted at Service Bus is stripped from the request since leaving it in the request would potentially result in an elevation of privilege for the listener, coming in possession of a token that also permits sending.

If the application wishes to use end-to-end authorization token flow, it is suggested to use the special ServiceBusAuthorization header as shown here, which frees up the Authorization header for end-to-end flow. Service Bus primarily supports the Authorization header directly for cases where the HTTP client library or framework does not provide the ability to add custom headers.

protected override void OnLoad(EventArgs e)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Add("ServiceBusAuthorization", this.sendToken);
    var image = client.GetStreamAsync(this.sendAddress + "/image").GetAwaiter().GetResult();
    this.pictureBox.Image = Image.FromStream(image);
}

##Running the sample

You can run the client from Visual Studio or on the command line from the sample's root directory by starting client/bin/debug/client.exe. You must run the service from Visual Studio or the command line, preferably with start service/bin/debug/service.exe into a separate, parallel command window, and the service must report itself as listening before you can start the client. You can start the service multiple times to see how load balancing works.