Azure Cookbook: Tasks To Make Azure Development Easier
Azure Cookbook: Tasks To Make Azure Development Easier
Azure Cookbook: Tasks To Make Azure Development Easier
Cookbook
Tasks to make Azure development easier
This document details common tasks that many Azure applications require, but are not
obvious how they might be implemented. This is a work in progress and additional tasks will
be added based on community feedback!
Table of Contents
Azure Service & Claims Authentication Development Guide.......................................................................2
Convert WCF service to work in Azure....................................................................................................2
Steps....................................................................................................................................................2
Convert azure WCF service to use SSL.....................................................................................................3
Steps....................................................................................................................................................3
Provisioning for claims based authentication (ADFSv2)...........................................................................6
Steps....................................................................................................................................................6
Add claims based authentication.............................................................................................................7
Steps....................................................................................................................................................8
Claims enable a Silverlight application..................................................................................................14
Steps..................................................................................................................................................15
Azure + Silverlight + Intranet Hybrid applications..................................................................................17
Steps..................................................................................................................................................17
Troubleshooting Issues..........................................................................................................................18
The HTTP request was forbidden with client authentication scheme 'Anonymous'..........................19
Could not establish trust relationship for the SSL/TLS secure channel with authority......................19
IIdentity.Name is null.........................................................................................................................19
Things to consider.................................................................................................................................20
Choosing a service account name......................................................................................................20
Service name is case sensitive...........................................................................................................20
Samples.....................................................................................................................................................21
Running the samples.............................................................................................................................21
Trouble Shooting Samples.................................................................................................................21
Azure Service & Claims Authentication Development Guide
This guide is a combination what can be found in the WIF (Windows Identity Foundation) Labs and other
guides. The purpose of the guide is to be more of a reference once you’re familiar with the concepts in
those guides, or as a quick reference to perform particular tasks.
The guide is organized into a number of common tasks that you may want to perform. Each task has a
set of detailed steps to ensure easy completion.
This guide makes use of a lot of content that was published in the following areas:
http://support.microsoft.com/kb/971842/
In addition to the patch, you’ll need to ensure you’ve installed the required software for Azure
development.
Steps
Here are the steps required to upgrade any WCF service to correctly work with Azure:
1. Create your service if not already done so in your Azure Webrole that you want to host the
service in.
2. Add the following behavior to the Web.Config, which in combination with the installed patch
will fix the issue of WCF returning the internal Uri’s when exposing the WSDL.
The port numbers in the xml below should be changed to match those of your services
endpoints. Therefore when running on the Dev Fabric, you will want to use 81 and 444 unless
you’ve specified specific ports in your configuration.
<behaviors>
<serviceBehaviors>
…
<behavior name="httpAzureBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="http" port="80" />
<add scheme="https" port="443" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
3. Add the new behavior to your service as shown below in this service example
<system.serviceModel>
…
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
5. Next you need to ensure your service class has the following attributes applied.
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
6. Deploy to Azure!
After completing these steps your service should be ready to be deployed to the Azure cloud.
Note: If you plan on using a Silverlight client with this service you must include either the
crossdomain.xml file or the clientaccesspolicy.xml file in the root of the Webrole. Sample copies of
these files have been included with this package.
Steps
1. Create a certificate if you don’t have one already. To do so run the following script that is
included with this package. To ensure you have the correct paths setup you should use the
Visual Studio Command Prompt in Administrator mode.
When supplying the service account name use the one you’ve created in Azure in all lower case.
The script will add the cloudapp.net suffix for you and create a Certs folder with your new certs.
The password is the one used to secure your certificate, and will be asked for again in two
dialogs as the script runs, be sure to use the same one each time. When using this cert locally
such as in the Dev Fabric you’ll encounter warnings that the cert is not valid, however you can
ignore those. When deployed to the Azure production slot, the cert name you specified will
match and therefore won’t show these warnings.
2. Once you’ve created your cert install the cert into your personal certificates location on your
machine. The easiest way is to run the Local Machine Certificates.msc command included with
this package. Then right click on Personal->Certificates and select All Tasks->Import. Select the
.pfx file from the Certs directory (note the .cer file will be selected by default). Use the password
you used to create the certificate when prompted, and then keep clicking next until finished.
Note: If you right click on the pfx file to import it, the file will be added to the Current User
store which will not be visible when attempting to add it to your Azure project. If this is the
case, you need to manually move the cert to the Local Machine/Personal/Certificates folder as
indicated in the diagram.
3. Next upload the pfx certificate into the service account for the application in the Azure portal.
This has to be done manually prior to deploying any secure services. Note that you want to add
the certificate to the service account and not the API certificates section.
4. Add the cert to the Webrole that contains your WCF service, using the same name as the
domain it was registered with. This can be done via the properties of the Azure solution.
5. Add the new cert to the Https end point for the WebRole
6. Ensure the role is running in full trust, which it will be by default. However, its best to check
incase it’s been changed.
7. Add a new behavior to your Web.Config which is essentially the same as the one used for http
but is configured for https support. See Convert WCF service to work in Azure for more details on
this step.
<behaviors>
<serviceBehaviors>
…
<behavior name="httpsAzureBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="http" port="80" />
<add scheme="https" port="443" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
8. Add the new behavior to your service as shown below in this service example
<service behaviorConfiguration="httpsAzureBehavior"
name="SampleService.GetClaims">
…
</service>
9. To support https a new binding is required, so you need to add the following custom binding
definition to your Web.Config file. If you already have a custom binding section, just add the
new binding.
<system.serviceModel>
<bindings>
<customBinding>
<binding name="httpsBinding">
<binaryMessageEncoding />
<httpsTransport allowCookies="true" />
</binding>
10. Update the bindings on your service to make use of this new binding
<service …>
<endpoint address="" binding="customBinding" bindingConfiguration="httpsBinding"
contract="SampleService.IGetClaims" />
Note: If you've already deployed your solution after completing Convert WCF service to work in Azure,
then you may need to delete the instance and redeploy rather than doing an upgrade. This is due to
adding a new https endpoint. Once deployed an upgrade can't add new endpoints.
Steps
1. Visit https://corp.sts.microsoft.com/onboard/adfsonboard.htm
2. Define the end points you want for your applications. It’s recommended that you try and
provision as many as you know about up front to reduce the amount of back and forth you’ll
need in getting this up and running. Therefore as a recommendation you should request the
following:
Note: The port number for the Dev Fabric is dependent on how you’ve configured your https
endpoint in the configuration, see Convert azure WCF service to use SSL step 5. By default your
SSL port will be 443, however if you have IIS installed and have a https binding then that port
will already be taken, so when the Dev Fabric starts up it will auto-increment the port number
until it finds a free one. So in some environments it will be port 444, hence defining this port
above. In production the port will be 443 unless you change it. You can check what ports your
Dev Fabric is using by looking at the Dev Fabric UI settings:
3. Ensure that all endpoints have a trailing slash as this will cause exceptions later if they don’t.
4. Ensure you’ve specified https as the STS requires https.
5. Determine what claims your application needs as a minimum you might want the following.
However, you can check out the full list here:
https://corp.sts.microsoft.com/FederationMetadata/2007-06/FederationMetadata.xml
Note: At present when roles are returned they are returned using their SID, which isn’t the
nicest form, especially if you’re accustomed to Windows Authentication. However, there is a
project called Matrix which is looking to address this problem. You can find out more
information here: http://bit.ly/b5Utyl
6. Complete the onboarding document with the above details and submit.
As a quick refresher, the above diagram shows the flow of claims when using ADFSv2 and WIF. The steps
in the diagram are:
Note: Before you can follow the steps for claims based authentication, you need to ensure you’ve
installed WIF (Windows Identity Framework) and the WIF SDK which provides tools for Visual Studio.
Steps
1. Run the Add STS Reference command by right clicking the WebRole project and selecting the
command from the context menu.
The config section at the top should have the Web.Config for you project and generally can be
left as is. However, the Application URI is the full https path to your web site. Here are some
examples:
<services>
<!--<service behaviorConfiguration="httpsAzureBehavior"
name="SampleService.GetClaims">
<endpoint address="" binding="customBinding"
bindingConfiguration="httpsBinding" contract="SampleService.IGetClaims" />
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
…
</services>
Then go back to Step 1 – this time the dialog asking about services should not show up.
Note: If you’ve not on boarded your application you need to follow the steps in Provisioning for
Claims based Authentication (ADFSv2) section.
4. Now add the detail of the corporate ADFSv2 STS. The Uri needed is
https://corp.sts.microsoft.com/FederationMetadata/2007-06/FederationMetadata.xml
Note: If you navigate to the ADFSv2 Url you’ll get the meta-data for the STS which will detail all
the claims available.
5. Next you need to choose if you want your tokens encrypted. This is optional; however it would
be good practice to use it in production sites.
6. The next screen details the claims supported by the token service
Note: The claim Uri for windowsaccoutname differs from what is specified in the Web.Config
and the screen above. The Web.Config has http://schemas.microsoft.com/ws/2008/
06/identity/claims/windowsaccountname. However the actual claim Ui is
http://schemas.xmlsoap.org/claims/windowsaccountname.
Note: If you’re using Visual Studio 2010 you may not see this dll in the references dialog. If that’s
the case you can manually add the reference with this path: . This path may differ
depending on where you’ve installed the WIF framework.
10. Due to WIF not being part of Azure yet, you need to modify the Reference
Microsoft.IdentityModel which was added by the wizard to be CopyLocal=True. This will force
the dll to be copied up to Azure into the local directory.
11. Create a Global.asax file for the WebRole if one is not present
12. Add the following element to the new Service element created by the Wizard:
<microsoft.identityModel>
<service>
…
<certificateValidation certificateValidationMode="None" />
13. When you are using the Dev Fabric, you need to modify the generate configuration so that the
local environment is recognized. To do this you need to modify the service element that was
generated to include the Dev Fabric Uri.
<audienceUris>
<add value="https://127.0.0.1:444/" />
<add value="https://devaccountname.cloudapp.net/" />
</audienceUris>
<federatedAuthentication>
<wsFederation passiveRedirectEnabled="true"
issuer="https://corp.sts.microsoft.com/adfs/ls/"
realm="https://devaccountname.cloudapp.net" requireHttps="true" />
<cookieHandler requireSsl="true" />
</federatedAuthentication>
14. Add the following code to the Global.asax.cs file. You only need to include the securing of tokens
if you chose to use encrypted tokens when setting up the STS reference.
using System;
using System.Collections.Generic;
using System.Web;
using Microsoft.IdentityModel.Web;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Web.Configuration;
using System.Text;
e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);
}
/// <summary>
/// Retrieves the address that was used in the browser for accessing
/// the web application, and injects it as WREPLY parameter in the
/// request to the STS
/// </summary>
void WSFederationAuthenticationModule_RedirectingToIdentityProvider(object sender,
RedirectingToIdentityProviderEventArgs e)
{
//
// In the Windows Azure environment, build a wreply parameter for the SignIn
request
// that reflects the real address of the application.
//
HttpRequest request = HttpContext.Current.Request;
Uri requestUrl = request.Url;
StringBuilder wreply = new StringBuilder();
if (!request.ApplicationPath.EndsWith("/"))
wreply.Append("/");
e.SignInRequestMessage.Reply = wreply.ToString();
}
FederatedAuthentication.WSFederationAuthenticationModule.RedirectingToIdentityProv
ider += WSFederationAuthenticationModule_RedirectingToIdentityProvider;
}
Note: The default encryption strategy followed by WIF for session tokens is to use DPAPI, would
create problems when the client interacts with multiple instances: a session token encrypted by
a given instance would not be readable by any other. As an alternative you will use the service
certificate for securing the session. The mechanism that WIF provides for customizing the way in
which session tokens are processed consists in providing a custom SessionSecurityTokenHandler
class. This is only relevant when encrypting your tokens.
15. The application should now be claims enabled with the internal ADFSv2 server.
Note: The passive authentication method discussed in this task will not work in an out-of-
browser (OOB) scenario. To work in OOB you need to use the active method, which is currently
not covered in this document.
The process of authenticating using Silverlight is different in that Silverlight doesn’t have native support
for claims based authentication. The above diagram shows the flow of claims for a Silverlight based
application and the use of the custom service AuthenticationService.svc, provided by the WIF team to
provide credentials to the Silverlight Application. The steps in the diagram are:
Steps
1. Create or add a Silverlight application to the Azure solution.
2. Add a reference to the SL.IdentityModel dll to the Silverlight application which is part of this
guides package.
3. Add a reference to the SL.IdentityModel.Server.dll to the WebRole of your WCF service.
Note: This is a modified version that comes with the WIF SDK. The version that comes with the
SDK will not work in Azure as is. It’s missing the following attribute on the Authentication
service class:
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
7. Add the following XML to the Web.Config under the configuration section to allow anyone to
access the service:
<location path="AuthenticationService.svc">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
8. Add the following namespace, which references the Silverlight version of the Identity model
provided by the WIF team to the App.xml in the Silverlight Application:
xmlns:id="clr-namespace:SL.IdentityModel.Services;assembly=SL.IdentityModel"
9. Now add the following Xaml to the App.xml file, which will instantiate the claims identity
manager that is used to handle claims authentication in Silverlight.
<Application.ApplicationLifetimeObjects>
<!-- Passive Authentication-->
<id:ClaimsIdentitySessionManager >
<id:ClaimsIdentitySessionManager.IdentityProvider>
<id:WSFederationSecurityTokenService/>
</id:ClaimsIdentitySessionManager.IdentityProvider>
</id:ClaimsIdentitySessionManager>
</Application.ApplicationLifetimeObjects>
10. In the constructor of the Main.xaml (or the main Xaml page you're using) add the following
event handler which will trigger the authentication. The authentication is actually performed by
calling the authentication service which was added in a previous step, and asking it for the
token.
using System;
using System.Linq;
using SL.IdentityModel.Services;
using SL.IdentityModel.Claims;
public MainPage()
{
InitializeComponent();
ClaimsIdentitySessionManager.Current.GetClaimsIdentityComplete += new
EventHandler<ClaimsIdentityEventArgs>(this.Current_GetClaimsIdentityComplete);
…
}
if (identity.IsAuthenticated)
{
Claim userAccount = identity.Claims
.Where<Claim>(c => c.ClaimType == userAccountClaim)
.SingleOrDefault();
The first option is great if you need your application to be used outside of CorpNet. However, for
internal applications, the easiest route would be option 2. The issue is option 2 doesn’t work out of the
box! The issue lies in the Azure application belonging to the Internet zone and your internal services
belonging to the Intranet zone. It seems Silverlight denies cross zone communication by default!
Note: For more details on this see the following Url: http://msdn.microsoft.com/en-
us/library/cc189008(VS.95).aspx
Steps
1. Add either you site or the Azure root domain to the local intranet zone. This can be done in IE by
selecting Alt (brings up the menu) then:
This should bring you to the same area you have in diagram 3.
2. Then enter either the domain of your site or the root of the Azure cloud.
http://*.cloudapp.net
3. You should now be able to access your internal services via your Silverlight Application. It should
be noted that you can continue to use Windows Authentication as you previously did if you
were using it. You can combine claims with the cloud with Windows Authentication for the
intranet.
Figure 3 - Local Intranet Zone
Troubleshooting Issues
This section attempts to help solve some of the more common issues that arise during development of
Azure solutions.
The HTTP request was forbidden with client authentication scheme 'Anonymous'
This error is typically caused by the client certificate not being installed correctly. It’s important to note
that when you create a self-signed certificate it will have a non-exportable private key. This means that
the certificate will work fine on the machine in which it was created, however if the same certificate is
used on another machine you will get this error. Where you want to share a certificate you must create
one with an exportable private key (-pe option in makecert). To make this easier however, you can use
the CreateCert.cmd which will generate the .pfx and .cert files you need. See the task Convert azure
WCF service to use SSL step 1 for details on how to run this command.
Note: If you right click on the pfx file to import it, the file will be added to the Current User store which
may not be visible to the tool you’re using. If this is the case, you need to move the cert to the Local
Machine/Personal/Certificates folder manually as indicated in the diagram.
Could not establish trust relationship for the SSL/TLS secure channel with authority
This error is due to the certificate not matching the domain you’re using or due to the cert not being
trusted. As a work around during development you can intercept the validation of the certificate and
provide your own logic. The routine below will allow un-trusted and domain mismatches to be valid. It
should be noted that this code really should only be used in development and not put into production.
IIdentity.Name is null
If you are not getting a value populated for the IIdentity.Name, this is probably due to the claims you’re
requesting. The good news is that you can actually get WIF to use any claim for this value, you just need
to configure it. The following is what needs to be added to your configuration which specifies the claim
to be used. In this case its http://schemas.xmlsoap.org/claims/windowsaccountname.
<service>
…
<securityTokenHandlers>
<remove type="Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<add type="Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35">
<samlSecurityTokenRequirement>
<nameClaimType value="http://schemas.xmlsoap.org/claims/windowsaccountname" />
</samlSecurityTokenRequirement>
</add>
</securityTokenHandlers>
Things to consider
This section is about things that you need to consider when doing Azure development or deployments.
It’s a section that will grow over time as new best practices are developed.
Choosing a service account name
When choosing a service account name keep in mind that you’ll probably want to use the same name
for your storage account too. The gotcha is that the storage account Uri only accepts numbers and
letters; however the service account Uri will accept any valid Uri. The difference stems from a
requirement for REST services that the storage account adheres to. Where this might be an issue is if
you decide to use a service account name like the following:
Note: the samples need the code to be cleaned up, but should still be functional. Also work is
still needed in this section to explain samples better. Feedback is appreciated!
Convert WCF service to work in Azure: This sample provides a simple console Application which
can be used to test against [L]ocalhost, [A]pp Fabric and the [C]loud:
Convert Azure WCF service to use SSL
Add claims based authentication
Claims enable a Silverlight application
For the samples that make use of IIS and SSL you will need to create a https binding on port 443 to a
certificate with a name of localhost.