Exercise 1: Using Windows Identity Foundation with a WCF Service in Windows Azure

This exercise will walk you through the process of creating a WCF role, configure its service to trust an on-premises development STS, attach a client and run the entire solution in the Compute Emulator. This is easily accomplished with only minor modifications to the procedure you would have followed for obtaining the same result on premises. The main changes accommodate the fact that in Windows Azure a service is hosted at different addresses according to the environment (local, staging, production), a situation you would have to deal with in any multi-staged environment.

You will start in Task 1 by implementing a simple weather service and testing its behavior without authentication using a client provided by the lab. Afterwards in Task 2, you will use WIF tooling to establish a trust relationship between the weather service and a local STS, by configuring the WCF service binding and behaviors collection in a way that will make the service require tokens from LocalSTS from all its future callers. Then in Task 3 and 4, you will set up an HTTPS secure endpoint between the WCF service and the STS using an X.509 certificate, using the Windows Azure Visual Studio tooling UI for associating it to the RelyingParty WCF Service Role. You will also enable the weather service HTTPS endpoint port. Finally in the verification, you will update the client to test the HTTPS endpoint of the weather service.

Task 1 – Implementing the Weather Service

The sample Relying Party application you will build in this lab will simulate a service providing weather-related information, hosted on a WCF Role of Windows Azure. In this task, you will open a Windows Azure Project project with a WCF Role already created. Then, you will implement the Weather Service and verify its behavior using a client provided by the lab.

Note:
You require an STS project and appropriate certificates to complete this exercise. If you have not already done so, complete the Getting Started section.
  1. Open Microsoft Visual Studio 2010 with administrator privileges. From Start | All Programs | Microsoft Visual Studio 2010, right-click Microsoft Visual Studio 2010 and select Run as administrator.
  2. Open the WIFWCFonWindowsAzure.sln solution file from the \Source\Ex1-UsingWIFandWCF\Begin folder of this lab.
  3. You will first setup some basic configuration for running the WCF Role. In the Solution Explorer, double-click the RelyingParty node inside the Roles folder of the CloudConfiguration project to bring up its properties page.
  4. In the Configuration tab, make sure that .NET trust level is set to Full Trust, and uncheck the HTTP endpoint check box inside the Startup action section to avoid launching the browser when you run the CloudConfiguration project.

    Note:
    If you can’t uncheck the HTTP endpoint check box, close Visual Studio, and open it again as Administrator.

    Figure 1

    Configuration for not launching the browser.

  5. Now, you will set the WCF Service Web Role endpoints configuration. To do this, select the Endpoints tab and set the Public Port to 8000 for Endpoint1. This will make the service to be available in port 8000.

    Figure 2

    Configuring HTTP WeatherService endpoint

    Note:
    The port value above are meant to avoid collisions with other processes listening for connections on the local machine. A typical example of this would be IIS, which usually reserves the use of ports 80 and 443 for itself. If you pick ports that collide with ports already in use by other processes, DevFabric will assign to your service random ports making development difficult. If port 8000 is already in use in your machine, make sure you choose a different port accordingly.

  6. You will now provide an implementation of the weather service. To do this, right-click the RelyingParty project and select Add | Existing Item.
  7. In the Add Existing Item dialog, navigate to the Assets\Service folder inside the Source folder of this lab, select the IWeatherService.cs and WeatherService.svc files and press Add. These files set up a weather service, which provides random 3 and 10 day forecasts based on a given zip code.

    Figure 3

    Adding WeatherService files to the RelyingParty

  8. You will now test the service behavior using the Client project that is already included in the solution. To do this, press Ctrl + F5 to run the Cloud project without attaching the Visual Studio debugger. The Compute Emulator and the Storage Emulator will be launched.

    Figure 4

    Opening the Compute Emulator UI

  9. Right-click the Azure icon tray and select Show Compute Emulator UI. In the Windows Azure Compute Emulator, ensure that the service has started successfully browsing the tree at the left panel looking for the RelyingParty role.

    Figure 5

    Checking that the RelyingParty role is running correctly

  10. Back in Visual Studio, right-click the Client project and select Add Service Reference. The service will be listening on the localhost (127.0.0.1) on the port we specified in previous steps, that is to say 8000. Enter http://127.0.0.1:8000/WeatherService.svc on the Address text box, and then press Go.

    Figure 6

    Adding a Service reference to the RelyingParty running on Compute Emulator

  11. Leave the default Service Namespace and press OK to add the reference to the WCF Service.
  12. You will now set up the Client project that is included in the solution to consume the weather service you just added. To do this, right-click the ForecastForm node, select View Code, and add the following statement.

    (Code Snippet – WebServicesAndIdentityInTheCloud Lab - Ex01 ForecastForm using statement)

    C#

    using Client.ServiceReference1;

  13. Replace the ShowForecast method implementation with the following code:

    (Code Snippet – WebServicesAndIdentityInTheCloud Lab - Ex01 ForecastForm consuming weater service)

    C#

    private void ShowForecast(int days, int zipCode) { using (WeatherServiceClient relyingParty = new WeatherServiceClient()) { WeatherInfo weatherInfo = null; try { this.Cursor = Cursors.WaitCursor; this.sourceLabel.Text = "Loading..."; if (days == 3) { weatherInfo = relyingParty.GetThreeDaysForecast(zipCode); } else if (days == 10) { weatherInfo = relyingParty.GetTenDaysForecast(zipCode); } this.DisplayForecast(weatherInfo.Forecast); this.sourceLabel.Text = string.Format( CultureInfo.InvariantCulture, "Source: {0}", weatherInfo.Observatory); } catch (MessageSecurityException ex) { this.sourceLabel.Text = string.Empty; MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); relyingParty.Abort(); } finally { this.Cursor = Cursors.Default; } } } private void DisplayForecast(Weather[] forecast) { this.forecastPanel.Controls.Clear(); for (int i = 0; i < forecast.Length; i++) { PictureBox pic = new PictureBox(); GroupBox box = new GroupBox(); box.Text = string.Format( CultureInfo.CurrentCulture, "{0:ddd dd}: {1}", DateTime.Today.AddDays(i), forecast[i]); box.Height = 145; box.Width = 130; pic.Dock = DockStyle.Fill; pic.SizeMode = PictureBoxSizeMode.CenterImage; box.Controls.Add(pic); switch (forecast[i]) { case Weather.Sunny: pic.Image = Resources.Sunny; break; case Weather.Cloudy: pic.Image = Resources.Cloudy; break; case Weather.Snowy: pic.Image = Resources.Snowy; break; case Weather.Rainy: pic.Image = Resources.Rainy; break; } this.forecastPanel.Controls.Add(box); } }
    FakePre-bd1ca3c8f8134e0dbb64587830cc9f51-2c63d15bca284f82a06d01296cd88a53FakePre-acff005c40244b44b846cca9855b6da6-3dc39451e63d43f1a291d220146c44c7FakePre-71767328fdc646e5beb5d2245296dbf9-8695e41e7baa47f08a4e9d2849389292FakePre-e8dcbfcddc6545c7a376b5c194753183-b9317544f2984b01a0e9dc816b4c6da7FakePre-94ba3b59f7054083972e56103bd6c946-575c9cac9da7463a95857d465e38238fFakePre-5676aa43f8d74e37bbe5d5503e0b8a2d-f3f631104c9342e2afcf45f3e7c5dca6FakePre-c6b47b28aea2444aa03a86feedb4f86a-cea682e5a7ec413d9342ff4cdf39eea8
    

  14. To test the weather service behavior without authentication, right-click the Client project and select Debug | Start new instance.
  15. In the Weather Station client, enter any Zip Code (for example: 1000) and press the Get 3 Days button. You should get the forecast for the following 3 days.

    Figure 7

    Getting the forecast for the following 3 days (note that the port number might be different)

  16. Close the Weather Station client.
  17. Stop the WCF Service Web Role running on Compute Emulator from its UI. To do this, right-click the Compute Emulator and Storage icon on the Windows’ tray bar and select Show Compute Emulator UI. In the tree at the left panel, right-click the current deployment and select Remove.

Task 2 – Establishing a Trust Relationship between the WCF Service and the Development STS

Now that we have the WCF service running and the STS, it’s time to establish a trust relationship between them. In practical terms, that means that the WCF service binding and behaviors collection will be configured in a way that will make the service require tokens from LocalSTS from all its future callers. The bulk of the task will be performed by the WIF tooling, and specifically the Add STS Reference wizard (which in turn is the Visual Studio integration of fedutil.exe, a standalone tool provided in the WIF SDK).

  1. Open the Web.config file of the RelyingParty project by double-clicking it in the Solution Explorer.
  2. The fedutil.exe tool expects to find the WCF service configuration within the local Web.config file. But since WCF for .Net Framework 4 relies on a machine level configuration file, a temporal service element needs to be added to the default configuration. To do this, add the following services configuration inside the <system.serviceModel> section.

    XML

      <system.serviceModel>
    FakePre-37f31dad74974cd49de17e616e863d1d-3077b692eea64ae1beeec83dc378725c <services> <service name="RelyingParty.WeatherService"> <endpoint address="" binding="basicHttpBinding" contract="RelyingParty.IWeatherService" /> </service> </services>FakePre-461c6fc6f2874486b75fc99730ed3221-9401479b27ec48309b40503b8f01d64aFakePre-1d7c932dc70946aaa72a1c71fa26718f-808db9a62d8e4fd6a13e69c6fea88746FakePre-6e8f41b3401f471a8a0a066056076559-601ff0af8b4a41c8bbf3736bd524be33FakePre-665c6c240fd94012baabf13c3515b753-40e5837846dd43199427ad9efee3a993FakePre-9a78c38c134b4f25a73487fe1aa44b71-12ca0c9bd6674f628a09de0edf00641e

  3. Press Ctrl + S to save the Web.config file and close it.
  4. Right-click the RelyingParty project and select Add STS reference. The Federation Utility will be displayed.

    Note:
    If the Add STS Reference item is not shown in the contextual menu within Visual Studio 2010, you can manually launch the tool by executing the fedutil.exe command found in %ProgramFiles%\Windows Identity Foundation SDK\v4.0. Browse and select the RelyingParty Web.config as the Application configuration location.

  5. Enter https://{yourprojectname}.cloudapp.net/ as Application URI, changing the {yourprojectname} placeholder for your Windows Azure Hosted Service name, and press Next.

    Figure 8

    Specifying the project’s Application URI

  6. Press Next in the Application Information Wizard step.

    Figure 9

    Selecting the service to configure

  7. Here you specify the address of the STS you want to outsource authentication to, that is to say the LocalSTS project you created in the previous task. To do this, select the Use an Existing STS option. Set the metadata document location to https://localhost/LocalSTS and press the Test Location button (make sure not to include spaces at the end of the metadata document location field).

    The wizard will inspect the STS site searching for a metadata document and will find the FederationMetadata.xml file, which will be shown in a new browser instance. The full file path will be added in the metadata document location field in the wizard window. Close the browser and press Next.

    Figure 10

    Using existing STS created on the previous task

  8. In Security token encryption, choose Enable encryption. Use the certificate created on the Getting Started: Setting up the Certificates and Local STS section for the Relying Party selecting the Select an existing certificate from store option and pressing the Select Certificate button.

    In the Select certificate dialog, chose the {yourprojectname}.cloudapp.net certificate and press OK. Press Next to continue with the wizard.

    Figure 11

    Configuring encryption for the communication with the STS

  9. Press Next in the Offered Claims Wizard step.

    Figure 12

    Showing Offered claims by the STS

    Note:
    The Offered claims dialog lists all the claims that a RP application can request to the STS. Name and Role are the default claims which are hardcoded in the WIF STS template: if you would be running the wizard against a proper STS, for example an ADFSv2 instance in your organization, the list would change accordingly.

  10. Check the Wizard summary, and press Finish.

Task 3 – Adding the Certificates to the Relying Party

In the following steps you are going to configure the certificate created on the Getting Started: Setting up the Certificates and Local STS section, using the Windows Azure Visual Studio tooling UI for associating it to the RelyingParty WCF Service Role.

  1. In the Solution Explorer, double-click the RelyingParty node inside the Roles folder of the CloudConfiguration project to bring up its properties page.
  2. Select the Certificates tab. Add a new certificate clicking the Add Certificate button at the top of the page. Set the certificate’s name to {yourprojectname}.cloudapp.net and then click the button labeled with an ellipsis (...) of the Thumprint column.

    Figure 13

    Creating the Relying Party’s certificate

  3. In the Select a certificate dialog, choose the certificate named {yourprojectname}.cloudapp.net and press OK.

    Figure 14

    Configuring the certificate to the Relying Party. Note that the certificates listed here are all from the LocalMachine\Personal store

  4. Now, you will set the HTTPS WCF Service Web Role endpoint configuration. Select the Endpoints tab to enter to the endpoints’ configuration page.
  5. Click the Add Endpoint button. In the name column fill with HttpsIn,set the protocol to https,set Public Port to 8443 name and chose the {yourprojectname}.cloudapp.net certificate from the SSL Certificate name combo box.

    Figure 15

    Configuring endpoints for the Relying Party

    Note:
    The port values above are meant to avoid collisions with other processes listening for connections on the local machine. A typical example of this would be IIS, which usually reserves the use of ports 80 and 443 for itself. If you pick ports that collide with ports already in use by other processes, DevFabric will assign to your service random ports making development difficult. If ports 8000 and 8443 are already in use in your machine, make sure you choose different ports accordingly.

  6. Select the Configuration tab, and uncheck both check boxes inside the Startup action section to avoid launching the browser for the HTTP and HTTPS endpoints when you run the CloudConfiguration project.

    Figure 16

    Relying Party general configuration

  7. Press Ctrl + S to save the modified properties for the RelyingParty Role.
  8. Close the RelyingParty Role property page.

Task 4 – Configuring the WCF Service HTTPS Endpoint

In this task you will update the WCF Weather Service to use the HTTPS endpoint.

  1. Open the Web.config file of the RelyingParty project.
  2. Add a name to the behavior element as shown in the code below. Make the name of the behavior RelyingParty.WeatherServiceBehavior:

    XML

    <system.serviceModel>
    FakePre-2944203f398341c2b2b0ac40802af32e-7e88a1dabf254c0ea12eb1c9a3378d04FakePre-de1441fcb36f4659a3675a0a468b684c-bb682c77f7e14b76b40c858b1ec8ac69FakePre-028eb5257c5e446e99a2270327a9d4cf-04ae872f6f37435080c4094330818d75<behavior name="RelyingParty.WeatherServiceBehavior"> …FakePre-48b87f822abb4d3b83b09f3056dc21d0-644ebbc44fcf4c44988885680c78dc24FakePre-33a05c913ae44a26a6fe91d2d251953e-a96b7389361f4df1a4b7b5cf274917e5

  3. Add the configuration behavior for KB971842 to the behavior named RelyingParty.WeatherServiceBehavior inside the <system.serviceModel> configuration section.

    (Code Snippet – WebServicesAndIdentityInTheCloud Lab - Ex01 Configuration behavior)

    XML

        <system.serviceModel>
    FakePre-aba0f803d7ed4a9d9455bb7759adc491-d320266f42c6402ba816e0ec28af2fadFakePre-735b7619a17c445a899a22ca2c8c47cb-c78dcfec16924a22b55dfd0a853f0927FakePre-7c8c01a4946440ae8d0a341ff4692e0b-e53c210eafa743498929f93c14f5698eFakePre-15f7e5fbd9614a7b8af20b77490315b1-a1e137c4d8b14ec8b3b1dd8953288517FakePre-03826deeb5ad4f07a59a6a35f15a22dd-84f05a54521e4787b5a9fd206982ec77FakePre-338a4f0f0da74a0db35028d0a1c73cf0-48958f9d141b470ab9a998fd286ff3fbFakePre-80cd879d64d944f9abb429688af606ce-53b09ec48f1b434a8c3e594f5fee2e85FakePre-52ea345622c2464ba33196674f75c917-8d21d0a6a595486fb2bef80cad3d1242 <useRequestHeadersForMetadataAddress> <defaultPorts> <add scheme="http" port="8000" /> <add scheme="https" port="8443" /> </defaultPorts> </useRequestHeadersForMetadataAddress>FakePre-5bb287abac704486a33bbb71419d9e1d-77e21e61428f4faf82751b32d9d3fc45FakePre-8acef666e91449a5b57e9415233f4dc8-4bc28e1b2ef741ea9c80708975db9839FakePre-33ab6a13c6a747a5af602529d791dd9a-1810c34734364d0a904e3b6de9d96d74

    Note:
    WCF 3.5 default metadata publishing mechanisms do not work too well in Windows Azure. The issue is in the way in which URIs are included in WSDL documents: the default behavior will include the internal ports used by the Windows Azure load balancer, which are not addressable from external callers. As a result, you cannot simply create a service reference using the standard tools (svcutil or add service reference in Visual Studio). The issue is described in a KB article, which provides a hotfix for resolving the problem. The hotfix is listed among the prerequisites for the lab. The useRequestHeadersForMetadataAddress behavior configuration enables the hotfix and induces WCF to use the load balancer’s address instead of one internal node address.

    You can find further information at https://support.microsoft.com/kb/971842/.

  4. The wizard configured the service to use ws2007FederationHttpBinding, however we need to exercise more control in the way in which we handle messages. Remove the current ws2007FederationHttpBinding section inside bindings and add the following custom binding. Remember to update {yourprojectname} label with your Windows Azure Hosted Service name.

    (Code Snippet – WebServicesAndIdentityInTheCloud Lab – Ex01 CustomBinding)

    XML

    <system.serviceModel>
    FakePre-09369ad9ed5747cea9b62cf4dc2aeb5e-a894521e43994f008e2b72d654ae1e60FakePre-1adecb81188c4aa7aa0e615e3b24db0d-8f1aa9f052334acdb555d0dc0a9cb807 <customBinding> <binding name="RelyingParty.IWeatherService"> <security authenticationMode="SecureConversation" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" requireSecurityContextCancellation="false"> <secureConversationBootstrap authenticationMode="IssuedTokenOverTransport" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"> <issuedTokenParameters> <additionalRequestParameters> <AppliesTo xmlns="https://schemas.xmlsoap.org/ws/2004/09/policy"> <EndpointReference xmlns="http://www.w3.org/2005/08/addressing"> <Address>https://{yourprojectname}.cloudapp.net/</Address> </EndpointReference> </AppliesTo> </additionalRequestParameters> <claimTypeRequirements> <add claimType="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" isOptional="true" /> <add claimType="https://schemas.microsoft.com/ws/2008/06/identity/claims/role" isOptional="true" /> </claimTypeRequirements> <issuerMetadata address="https://localhost/LocalSTS/Service.svc/mex" /> </issuedTokenParameters> </secureConversationBootstrap> </security> <httpsTransport /> </binding> </customBinding>FakePre-4ab10e5bfff0448982a83e5a9c24d261-4ed26f5cec7c4fb7b89cbe48e7ab7bc4FakePre-a3279144e3ba4a0499a731912e6e7411-bf2b6e692ade45a6b3b2b81410002a0eFakePre-b54b9df06d554c69a5a7816ebde1f50b-d80cc39ee27a4271b32be438cbeb7372FakePre-82f4c225a0c3467f8d3b069117981f33-14f459cc56a147b4ad6561f44ae91d8bFakePre-31a27bd9ca4444d0b681acd485aa2f29-e1d5d60f87374f9bac12d7ab293a0bd9FakePre-d34f1bb13a1b44de9804601a15506a10-3a0ff50a75834487af45c74b6f275e1eFakePre-13fac8b40a05437a9285b0b2b2304fcf-d87b8f5cfe4d4850a3d8558c2aa57d47FakePre-ac1cfa81bf5946b59d5801c2d7d24a3e-8e6a584770bf45cd9ff0b69686360976FakePre-baabbced4cf34cf490a8027566761ecb-2fb081fd17c64b8fa8c209083c6c9b65FakePre-38a1149724a14275868c019e1adff4fd-c0cb48c653c1475388445e02bc3eaacfFakePre-a86b21201cfa466cbc6f9c8598554e18-7ef69375896a446d9077896f49620359FakePre-452725f0ec8e4d74afc2f95755cbf63f-96250909d21b4c4f9a6fa1c1d0b07162FakePre-1a500fae5e934ea69def53cc1186e5f8-1d6c686257af401db63a8934d00d72b4FakePre-407202301e7443c28d185a1124ba813d-de54b8e4ee6a4f48921513805fd6adc5FakePre-62f30d7b4e86404293f46a401ec9aad3-232d0abd0d2c470fa0b7fc86e9b80850
    Note:
    The main reason for which we need a custom binding is that we want to set the attribute requireSecurityContextCancellation of the <security> element to false hence moving to cookie mode. This will allow you, later in the lab, to take control of the session token and accommodate its processing to the load balanced environment of Windows Azure.

  5. Add the behaviorConfiguration attribute to the service named RelyingParty.WeatherService.

    XML

    <system.serviceModel>  
    FakePre-cd3fca50adfb4a7ba6bf892499b5b4fc-e7320d83706c431c8140ffc03cacfabaFakePre-6ea10d741fec4b2397c88d301a32a587-9ec96a0f7bea4af5b5e1f8c238ef8c36FakePre-b80239c1664d4e918a792a23c1d095a2-bb4f76f9abdc4023b676a62821c02f29FakePre-e181b77cc72a493bac8a02908b905621-15b4003ea7244149af7aa6d2f54b03dbFakePre-b3a8ca894d0c42d4aa22eeec4cea345b-9f0be5c99fdb4a7caa672af90f7bbeabFakePre-ad77b1f0e9da4736ac48b7a25ad534a7-18ebc072fa124f57b517df32668e6fe2

  6. Remove the hardcoded address created by Federation Utility from the endpoint configuration. To do this, replace the endpoint element with the one highlighted below:

    XML

    <system.serviceModel>
    FakePre-6ca1cd35df314cb88a2ba5d9a24785d1-03359e928db2459c9616b697d340b0c1FakePre-78b2711456ce4218b9208590f94804db-484070dc58764b2e936664425907bd0bFakePre-8309e2c696ef4ebea495cae3678631f7-71e7ad77bdac4c6f9762afff975abbdc <endpoint address="" binding="customBinding" contract="RelyingParty.IWeatherService" bindingConfiguration="RelyingParty.IWeatherService" />FakePre-8ad047c8b8ec41e7be96957d7f318133-07bd965bc369483a8b399fc4b3cf9478FakePre-a37363462238497d805abe59cd7f51d2-041fdd2976784a66b19d62c3948d38fdFakePre-f9ea95cba8f04360940e256ae486c43f-56dc8983ee6b43b4b9d1b7e3ad9a84c3FakePre-edf3db7b2b3b4081912842cd4f01d9a4-990606f5e9fe4839b09bca1b26c4bd71FakePre-1567584a85e7445abc2fdb914337990c-621d978666684388b1ad5a36b5a1bc7eFakePre-297e6d862b15464dace7bf227fcc601e-9c06e483e1204dca8220db05a51e66da

  7. Also add Mex endpoint that use the mexHttpsBinding binding (note the “s”):

    XML

    <system.serviceModel>
    FakePre-e1ab616aefcc4ace8222523999c86311-7be4cd37fd7341d2b5a985af85fb49dbFakePre-408f3d3ffd7b43cca6f51bd9b29827ba-ae51fe2281fc4c3aa46b1d4c068bcdf3FakePre-b975994988064602a45b147c17e75e78-5e1a89ed354a47768a450e1303a36255FakePre-fd4bae27e7534e76a30caca917a6d480-4e21cb8c96094ff4abb4e122e5608127FakePre-6369833659bf4d4bb41f31bde94e9d81-4504291f8a5a49308d25e852a3596884<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" /> FakePre-c03e29a2f9ee4f2e856065d5c7e47939-46095a0b08b8401eb5201734596fd31eFakePre-057a60f1355d49e1baa2d033b7d04b8c-29a754457efc4021ba58bcc5c86e2175FakePre-8c4263de1bc1416b9664d154b358c3e5-d3fbac570ee2426488ab82a04cb35536FakePre-5fbfea0ba922462f83a910dcc0b9e8f8-5ff91f325d404cefb7fbd37678b1d6c6

  8. The metadata retrieval from the WCF Service Web Role will also be over https. To enable this, replace the httpGetEnabled attribute inside the serviceMetadata element with httpsGetEnabled (note the “s”):

    XML

    <system.serviceModel>
    FakePre-03a1e649501d4903b66ffa0c02f807cf-b36142294b1249a09a3c20406b855709FakePre-1782949bb69343f4a6e42b9ec463c86a-9b264b918687485da8bd13d6840a0901FakePre-0d1c9bc6f08945349e042aebd113fd3c-45c22b166db94914accd7edd562595c2FakePre-06f6a04a66a447b592c66d0573d0edbd-5f67426f51164b38b9003b12a642f6cbFakePre-4c5a0732a3fd47e29e0684c08b9dd14e-d8e475110cd04afb8d7f43eafe0421a0<serviceMetadata httpsGetEnabled="true" />FakePre-aa1f0393683a4973bed8ab2f1599f3a3-4e49c9ea85cf4055a262295edd553ec1FakePre-25dcb53c5f1b419d82695385d7089a32-40a838a7b2b4425ebf629f6c8605432aFakePre-439bd97efaab46a7968542f8bdfe2e1d-531d62bd71b6450fabef682cdc12633aFakePre-67259b0447e3418f88b42f01f5bea09c-96cce67efcd74ae99a0327ac823f3223FakePre-27dccb1823c84a7699cff147664d6e6c-b6e47175e40244c7b613ef154fc32ac8FakePre-877b663ca2da45b8877831b3eae05ef1-a9ba5ab754fa474c800b619d4950da17FakePre-5d60cc55f1314923bc05e144db62ad1a-2803a8e7b90d4259a6fd5d09106e53a5FakePre-ef0dfa108aff468d8056ef60ffbc4e67-e7924ce493bf4b5382778b1fdf0d41d5FakePre-032c4c29bd464137a2d0e8c7729f91f0-5d2cdceb0bf7452490e7727d843367d1FakePre-90dac382b92248a297e6f7d206532956-e4144009682043ad9c7d68c70c363037FakePre-4e7b0a0baa60462596a6250cfb0f4a99-cd57d9c9b0a54ab1a52b8446933032aa

  9. Update the thumbprint attribute value for the LocalSTS trusted issuer with the one shown below. This is the thumbprint of the certificate that the LocalSTS is using for signing.

    XML

    <microsoft.identityModel>
    FakePre-e11385cfd67444559dc23b294c02a5b3-4e9e82983d124ffc827b677a55285125FakePre-a4da5294df19442d8371c012a5e4bbb0-9f551a1645ea41ed9d14fbf9514c3eb7FakePre-bd6cbd3609da48de865ac4cb324c6055-b66142760d214d88b6f6b39c6f48f7b4FakePre-cdab5d26d77444b0a583192ef0ebf47d-c50abbb81efa4c5db67bace75713e19aFakePre-2040d2b1516a44f2a227f71122626b21-50486a4d54e34c87a1a18e23d79b56a1FakePre-40aa0788d72546b2b7b72fec7c438829-5d554d645677403bb1f69ce6dd2c55a8<add thumbprint="40A1D2622BFBDAC80A38858AD8001E094547369B" name="https://localhost/LocalSTS/Service.svc" />FakePre-16e9e7c806f243ddbe6c8e5c389ac5a7-086d1c1afd404bc79dbde6f9eeb9d147FakePre-1abec8b9105b4f68bf8c9464b50932b8-d3547088838645558fc25c6ea904b74bFakePre-cf0239b4104447c89065480545b7f9bf-3302889ac166442c805a72553d1f2f02FakePre-fece993384b643e78c647a8ec1c0424d-56300b8c65d447a99086463ad57d1c80

  10. Press Ctrl + S to save the Web.config file and close it.
  11. You will configure the WeatherService to listen for request in any address where it is available. To do this, open the WeatherService.svc.cs file for the RelyingParty project, and add a ServiceBehavior attribute to the WeatherService class definition as it is shown on the following code.

    (Code Snippet – WebServicesAndIdentityInTheCloud Lab - Ex01 ServiceBehavior attribute)

    C#

    namespace RelyingParty
    FakePre-b6056208ee3e4e5c8eb19593979f9e8c-660c0d5023fe4170b93d6ad0cc691e44[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]FakePre-30c1a374b8b44cb498c5ca605099bd69-a7533fce35f642368f882c24eaf130f9FakePre-12f8a89d77064bb4bca1aad81233e500-9c220c56b97444818b26b9fe60c05874FakePre-2e1956b86a8e4a14a5aae325869fe5c3-cd039f081020417bb3c56a462daaa5e8FakePre-3236b7a2863a442e9c7368de4753e612-171fcee7f8b54e78a3e0e93418adeb99FakePre-97ae816d020746fab759d0b0474248b0-983753ebe00447028fc494a467679002

    Note:
    Decorating your service class with that attribute has the effect of turning off the address filter, so that incoming messages with different To elements are accepted.

  12. Press Ctrl + S to save the WeatherService.svc.cs file and close it.

Verification

Your service is finally ready to run using the certificates. You will now update the client to consume the project using the HTTPS encrypted endpoint.

In order to verify that you have performed every step in the exercise correctly, proceed as follows:

  1. Press Ctrl + F5 to run the Cloud project without attaching the Visual Studio debugger. The DevFabric will be launched. Proceed as in Task 1 to verify in the Compute Emulator that the service has started successfully.
  2. In the Client project, right-click the ServiceReference1 node inside the Service References folder and select Configure Service Reference.

    Figure 17

    Configuring the Client service reference

  3. The service will now be listening on the localhost (127.0.0.1) on the SSL port we specified in the earlier tasks, that is to say 8443. Enter https://127.0.0.1:8443/WeatherService.svc on the Address text box and press OK.

    Figure 18

    Weather Service configuration update

    Note:
    If it is the first time that you configure https bindings on Compute Emulator, you will get the following warning:

    To work around it, you have to copy the 127.0.0.1 certificate created by Windows Azure Tools for Visual Studio (which is available at LocalMachine\Personal store) to the LocalMachine\Trusted Root store. You can do that by using the certificates MMC in Windows.

    Another way to work around this is running again the SetupCertificate.cmd script, without providing any Windows Azure Hosted Service name. The script will copy the 127.0.0.1 certificate to LocalMachine\Trusted Root for you.

    Once you successfully performed one of the steps above, you can repeat the service reference step.

  4. Open the app.config file inside the Client project.
  5. Move the AppliesTo element from the trust:SecondaryParameters section to additionalRequestParameters. Remember to update {yourprojectname} label with your Windows Azure Hosted Service name.

    XML

    <system.serviceModel>
    FakePre-441797e276e348738c4263476a831647-348dbdd004034e2eaf9edf159efa1d8fFakePre-fd05403285a844c09496d127c24e3223-25de258f8a1245aab1df012c864a1af9FakePre-feb9bbd796484a42b5563f2cbb530496-1881a97ae14d4a2d906daea3e934cf8dFakePre-db1e0b40544b4c4580d87ccfdb144525-a1b563e0cf8e4467b624fe4d58197677FakePre-016b501f4215458d9de079d7328a61cd-daecddf3f4e245539138fb662a998237FakePre-5cb2d02d1ed74b47ba26e2dab56b214e-0183524e413e4ca7a1cd9f03b1a4df2aFakePre-0ffd3e2e987a4dc8a804cef9926814e2-f0e82d4c6c304e649bf8ed6416ad81f3FakePre-6379752133a94805b187afdd8110e174-efe443d43242408a9b01cb5287bfe85bFakePre-c696daf167ec4771a8b06d0701557627-c072e769dca84bfd8d7f69d76394db88<AppliesTo xmlns="https://schemas.xmlsoap.org/ws/2004/09/policy"> <EndpointReference xmlns="http://www.w3.org/2005/08/addressing"> <Address>https://{yourprojectname}.cloudapp.net/</Address> </EndpointReference> </AppliesTo>FakePre-e4519c6dcf384b859cef8b1f95834e5c-713d089c030543729995beaac6501a12FakePre-b7bd6f6c0c5e40c582243681db6e19a6-6ae706642005457c855323f38802244aFakePre-b51b92970e624fd2875fdac49365ad3c-cf00ee8b5d1f4b0aa75229884e936373FakePre-33241faa4c9945acb000e8bff596d587-c9088c256e8c4faa993510f6d64c9ab6FakePre-46f582ecd8234e78a3d1dfe0ebc78b7a-ee3202bf78364260840843ba41f0f534FakePre-4cc2b81443e14dba93716cef863727c1-2e3e38650f4545639eb8d798ab47dd07FakePre-79ba6a8547a44387824ac31cc78b42ad-46ced374c4f24e73aae4bee44befb40eFakePre-85489a4b87eb412ea4c4cb0167c60b62-b98818ff254a4552824c9b79094d0455FakePre-43f54b8627b540eaaf2174dd22334fc9-5836742c73074489a64315c921a1b93aFakePre-fb81627fec4149619596aa9e1441532b-442ff907c7114b54a9d6e227142547abFakePre-4e9db021e4f749eebc7a3439fd3abf21-c6b9ec806cb54f90a67c8b9130400a25FakePre-a4388c15bc2d4c02934631cb200e9a46-2d992749b8654038ac765181c21bd0adFakePre-d9025c457c2e4140a0d74a4aa6a7fdf4-6ab8d98253a1483696a0ef936fa3b837FakePre-7e0f48e1c25e4796984f950827a8104e-56d17dc6786244a9a5fa325ad66f6912FakePre-238e92a145ee4b4489563314b1425619-4306ee97e2104fc3abf9964219a36591FakePre-aa42990507724eb399670ccb8d9bf351-982648685d8b4f52ace598c74306d0e1

    Note:
    The RP provides indications about the desired AppliesTo value in the SecondaryParameters element, and svcutil does capture it in the client configuration. However the client has to explicitly accept the settings by moving them in the RST: after all, a compromised RP may try to spoof the token by providing malicious addresses overriding the AppliesTo.

  6. The client is finally ready to call the RelyingParty WCF Service. To test it, right-click the Client project and select Debug | Start new instance.
  7. In the Weather Station client, enter any Zip Code (for example: 1000) and press the Get 3 Days button. You should get the forecast for the following 3 days. Note that now the Source uses the https port.

    Figure 19

    Getting the forecast for the following 3 days (note that the port number might be different)

  8. Close the Weather Station client.
  9. Stop the WCF Service Web Role running on Compute Emulator from its UI. To do this, right-click the Compute Emulator and Storage icon on the Windows’ tray bar and select Show Compute Emulator UI. In the tree at the left panel, right-click the current deployment and select Remove.

    Note:
    In this first set of tasks you developed a simple but complete scenario. You created a certificate for your service, a cloud project with your WCF role and a local development STS. You learned how to use the WIF tooling for outsourcing the service authentication to an STS, what practicalities need to be handled for preparing a WCF service to run in Windows Azure and how to develop a client for the service. Finally, you verified that everything works by running the service in the DevFabric environment. That’s pretty much all you need to know for getting started to host in Windows Azure your own services and secure them; in the following Exercises we will explore more advanced aspects of the WIF and WCF synergy in Windows Azure.