Wednesday, 12 August 2015

Prism for the Windows Runtime Templates for Visual Studio 2015

I was recently asked if I had any plans to update the Prism WinRT templates to support VS2015. To be honest I was surprised that anyone is still using Prism WinRT, so had no plans to update the templates to VS2015. But in order to support people who’ve stuck with it, I decided to do an update. My intention was to add support for VS2015 to the existing template VSIX. However, this turned out not to be possible for two reasons:

  • Creating a Prism WinRT project relies on the Microsoft.VisualStudio.WinRT.TemplateWizards assembly. VS2012/2013 used v12 of this assembly, with VS2015 using v14. This presents a problem as a machine that only has VS2015 will only have the v14 assembly.
  • The location where the Prism WinRT project and item templates should reside has changed in VS2015.

The simplest solution was to build a new VSIX for VS2015.

I tried to upload the VSIX to the Visual Studio Gallery and it fails to upload, despite working when installing locally. This is because some of the paths in the VSIX would be too long if it’s installed on an Windows XP machine. While I can shorten the path a little, it’s not enough to pass Visual Studio Gallery validation. There are other solutions available but it’s not worth investing the time to solve the issue for these templates, when there’ll be a brand new set for Prism 6.

So in the meantime, if you want Prism WinRT templates for VS2015 you can download them from here.

Sunday, 5 July 2015

Revisiting Prism for Xamarin.Forms

Previously I wrote about how to create a flexible and maintainable Xamarin.Forms app with Prism. In the last month Prism for Xamarin.Forms has undergone some more work by Brian Lagunas, and a couple of new features have been implemented. This blog post will investigate the new features provided by the latest release of Prism for Xamarin.Forms.

Navigation

There are two improvements made to navigation in the latest release of Prism for Xamarin.Forms. The first concerns how you register types for navigation, and how to perform navigation to registered types. An overload to IUnityContainer.RegisterTypeForNavigation has been added that accepts two generic types. The first argument is the View type, with the second argument being a Class type (most likely a ViewModel type).

1 protected override void RegisterTypes()
2 {
3 Container.RegisterTypeForNavigation<PhotoPage, PhotoPageViewModel>();
4 }

A corresponding change has been made to INavigationService.Navigate method to accept a generic in place of a string to identify the View to navigate to.

1 public void Navigate()
2 {
3 ...
4 this.NavigationService.Navigate<PhotoPageViewModel>(parameters);
5 }


The advantage of this approach is that it allows you specify a ViewModel for navigation, eliminating the magic string that was previously used.

The second improvement relates to how the correct INavigationService instance is obtained in a ViewModel for navigation. The previous approach involved having your ViewModel implement the INavigationServiceAware interface. in order to add a NavigationService instance to your ViewModel. In the latest release of Prism for Xamarin.Forms the INavigationService can be directly injected into the ViewModel constructor.

1 public MainPageViewModel(INavigationService navigationService)
2 {
3 this.NavigationService = navigationService;
4 ...
5 }

Please note that in order for Prism to inject the proper INavigationService instance via the constructor, you must name the parameter navigationService. This is because each page in Xamarin.Forms has its own navigation instance. So Prism can’t just register a global navigation service for all pages. It has to have a navigation service specific to each page and ViewModel. Prism uses the Unity dependency injection container to resolve the service through constructor injection, and because Unity doesn’t allow you to look for a type Prism instead looks for a specific name, in this case navigationService.

DependenyService improvements

Xamarin.Forms provides the DependencyService class to enable shared code to easily resolve interfaces to platform-specific implementations. However, it is not always easy to test ViewModels that make a call to the DependencyService class. A typical implementation without Prism is shown below.

1 public MainPageViewModel()
2 {
3 _textToSpeech = DependencyService.Get<ITextToSpeech>();
4 SpeakCommand = new DelegateCommand(Speak);
5 }
6
7 private void Speak()
8 {
9 _textToSpeech.Speak(TextToSay);
10 }

Prism improves this experience by enabling you to ask for your dependency as an argument in your ViewModel constructor.

1 public MainPageViewModel(ITextToSpeech textToSpeech)
2 {
3 _textToSpeech = textToSpeech;
4 SpeakCommand = new DelegateCommand(Speak);
5 }
6
7 private void Speak()
8 {
9 _textToSpeech.Speak(TextToSay);
10 }

The advantage of this approach is that it eliminates the call to the DependencyService class, helping to make your ViewModel class more easily testable. For an example that demonstrates using Prism with the TextToSpeech see this sample app.

Summary

Prism for Xamarin.Forms provides loosely-coupled components that help you to produce Xamarin.Forms apps that are flexible, maintainable, and testable. The latest additions to Prism enhance the navigation experience and make it easier to test ViewModels that use the Xamarin.Forms DependencyService class.

The sample app can be downloaded here.

Wednesday, 13 May 2015

Creating a flexible and maintainable Xamarin.Forms app with Prism

Prism, a set of libraries developed by Microsoft, helps you to design and build apps using loosely-coupled components that can evolve independently but that can be easily integrated into the overall app. Prism now includes support for Xamarin.Forms in the form of a preview library. This library helps to produce Xamarin.Forms apps that are flexible, maintainable, and testable.

Prism is designed to help developers create apps that need to accomplish the following:

  • Address common app development scenarios.
  • Separate the concerns of presentation, presentation logic, and model through support for the Model-View-ViewModel (MVVM) pattern.
  • Use an architectural infrastructure to produce a consistent and high quality app.

The logical architecture of a typical Xamarin.Forms app that uses Prism is shown in the following diagram. Grey items are provided by Prism, with blues items having to be created by the developer.

image

In this blog post I’ll take the sample app developed in my previous blog post, and convert it to use Prism in order to further the separation of concerns in the sample app. I’ll assume that you are familiar with the Unity dependency injection container. However, you are not required to use Unity, or any other dependency injection container, in order to use Prism.

Implementation

Bootstrapping the app

The App class, in the XamarinPhotoViewer project, has the responsibility for bootstrapping the app.

1 public class App : Application
2 {
3 public App()
4 {
5 var bootstrapper = new Bootstrapper();
6 bootstrapper.Run(this);
7 }
8 }

This is achieved by using the App constructor to create an instance of the Bootstrapper class, and run it. The Bootstrapper class is simply a class that initializes the services that Prism will be using.

1 public class Bootstrapper : UnityBootstrapper
2 {
3 protected override Page CreateMainPage()
4 {
5 return Container.Resolve<MainPage>();
6 }
7
8 protected override void RegisterTypes()
9 {
10 Container.RegisterTypeForNavigation<PhotoPage>();
11 }
12 }

The Bootstrapper class derives from the UnityBootstrapper class, which is a Prism provided class that handles the initialization of the Unity container. The Bootstrapper class overrides the CreateMainPage method in order to return the page to be used as the root page of the app, and overrides the RegisterTypes method in order to register the PhotoPage view so that it can be used in navigation.

Connecting view models to views

Prism provides a view model locator object that is responsible for the instantiation of view models and their association to views. This has the advantage that the app has a single class that is responsible for the instantiation of view models.

The ViewModelLocator class has an attached property, AutowireViewModel that is used to associate view models with views. In the view’s XAML, this attached property is set to true to indicate that the view model should be automatically connected to the view.

1 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
2 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
3 xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
4 prism:ViewModelLocator.AutowireViewModel="true"
5 x:Class="XamarinPhotoViewer.Views.MainPage">
6 ...
7 </ContentPage>

The ViewModelLocator object uses a convention-based approach to locate and instantiate view models from views. This convention assumes that view models are in the same assembly as the view types, that view models are in a .ViewModels child namespace, that views are in a .Views child namespace, and that view model names correspond with view names and end with “ViewModel”.

Updating a view in response to changes in the view model

All view model classes that are accessible to the view should implement the INotifyPropertyChanged interface. This allows view models to provide change notifications to any data-bound controls in the view when the underlying property value changes. However, this can be repetitive and error prone. Therefore, Prism provides the BindableBase class that implements the INotifyPropertyChanged interface.

Each view model class in the sample app derives from the BindableBase class. Therefore, each view model class uses the SetProperty method in the BindableBase class to provide property change notification.

1 public class PhotoPageViewModel : BindableBase, INavigationAware
2 {
3 ...
4 private string _image;
5 public string Image
6 {
7 get { return this._image; }
8 set { SetProperty(ref this._image, value); }
9 }
10 ...
11 }

The call to the SetProperty method simply updates the value of the property if it has changed, and provides property change notification to the view.

For more information about data binding in Xamarin.Forms, see Data Binding Basics.

Triggering actions in the view model from the view

Apps typically invoke an action in response to a user action, such as a button click, that can be implemented by creating an event handler in the view’s code-behind file. However, in the MVVM pattern, the responsibility for implementing the action lies with the view model, and you should try to avoid placing code in the view’s code-behind file.

Commands provide a convenient approach to represent actions that can be bound to controls in the view. View models typically expose command properties, for binding from the view, that are object instances that implement the ICommand interface. XAML inherently supports commands and many controls provide a Command property that can be data bound to an ICommand object in the view model. For more information about Xamarin.Forms support for ICommand, see From Data Bindings to MVVM.

Prism provides the DelegateCommand class to implement commands in view models.

1 public DelegateCommand NavigateCommand { get; private set; }
2
3 ...
4
5 public PhotoPageViewModel(INavigationService navigationService)
6 {
7 ...
8 this.NavigateCommand = new DelegateCommand(GoBack);
9 }
10
11 private void GoBack()
12 {
13 this.NavigationService.GoBack();
14 }

The NavigateCommand is exposed to the view through a read-only property that’s initialized in the view model constructor.

1 <Button Command="{Binding NavigateCommand}"
2 Text="Go back" />

When the command is invoked from the view, it simply forwards the call to the GoBack method in the view model class via the delegate specified in the view model constructor.

Navigating between pages

The XamarinPhotoViewer sample app triggers navigation requests from user interaction in the views. These requests are to navigate between the MainPage and PhotoPage views.

Prism’s INavigationAware interface allows an implementing view model class to participate in a navigation operation. This interface defines the OnNavigatedFrom and OnNavigatedTo methods that are called during a navigation operation. The OnNavigatedFrom method allows the page being navigated away from to perform any cleanup before it is disposed of. In the view model class for the page being navigated to, its OnNavigatedTo method is called after navigation is complete. The OnNavigatedTo method allows the newly displayed page to initialize itself by using any navigation parameters passed to it. For example, the OnNavigatedTo method in the PhotoPageViewModel class accepts a Photo parameter that is used to display data on the view.

Prism provides the PageNavigationService class that allows view models to perform navigation operations without taking a dependency on UI types. When view model classes are instantiated, Unity will inject the dependencies that are required including the PageNavigationService instance. View models can then invoke the Navigate method on the PageNavigationService instance to cause the app to navigate to a particular view in the app, or the GoBack method to return to the previous view.

1 public void Navigate()
2 {
3 var parameters = new NavigationParameters();
4 parameters.Add("photo", this.Photo);
5 this.NavigationService.Navigate("PhotoPage", parameters);
6 }

The Navigate method accepts a string parameter that represents the page to be navigated to, and a navigation parameter that represents the data to pass to the page being navigated to. Any data being passed to the page being navigated to will be received by the OnNavigatedTo method of the view model class for the page type.

Placing the navigation logic in view model classes enables navigation logic to be exercised through automated tests. In addition, view models can then implement logic to control navigation to ensure that any required business rules are enforced.

Summary

Prism for Xamarin.Forms provides loosely-coupled components that help you to produce Xamarin.Forms apps that are flexible, maintainable, and testable. In particular, Prism’s support for MVVM enables you to easily provide a clean separation of concerns between the appearance and layout of the UI from the responsibility for the business logic. This helps to ensure that an app will be easier to test, maintain, and evolve.

The sample app can be downloaded here.

Tuesday, 12 May 2015

Creating a Xamarin.Forms app that uses the MVVM pattern

The MVVM pattern is well documented, and is used to cleanly separate the responsibility for the appearance and layout of the UI from the responsibility for the business logic.

In this blog post I’ll explore using Xamarin.Forms and the MVVM pattern to create a simple photo viewer app. For more information about Xamarin.Forms and MVVM, see From Data Bindings to MVVM.

Implementation

Bootstrapping the app

The App class, in the XamarinPhotoViewer project, has the responsibility for bootstrapping the app.

1 public class App : Application
2 {
3 public App()
4 {
5 // The root page of your application
6 MainPage = new MainPage();
7 }
8 }

This is achieved by using the App constructor to set the MainPage property to an instance of the page, in this case MainPage, to be displayed when the app starts.

Connecting view models to views

The simplest approach for connecting a view model to a view is for the view to declaratively instantiate its corresponding view model in XAML. When the view is constructed, the corresponding view model object will also be constructed.

1 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
2 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
3 xmlns:viewmodels="clr-namespace:XamarinPhotoViewer.ViewModels;
4 assembly=XamarinPhotoViewer"
5 x:Class="XamarinPhotoViewer.Views.MainPage">
6 <ContentPage.BindingContext>
7 <viewmodels:MainPageViewModel />
8 </ContentPage.BindingContext>
9 ...
10 </ContentPage>

When the MainPage view is created by the App class, an instance of the MainPageViewModel class is automatically constructed and set as the view’s BindingContext. This approach requires the view model class to have a parameterless constructor.

An alternative approach is for the view to set its BindingContext in the code-behind file.

1 public partial class PhotoPage : ContentPage
2 {
3 public PhotoPage(object photo)
4 {
5 InitializeComponent();
6 this.BindingContext = new PhotoPageViewModel(photo);
7 }
8 }

The programmatic construction and assignment of the view model within the view’s code-behind has the advantage that it allows parameters to be passed into view model constructors.

Displaying view model data on the view

The MainPage class defines the XAML used to display a collection of photo thumbnails, in a ListView control.

1 <StackLayout>
2 <Label Text="{Binding PageTitle}"
3 HorizontalOptions="Center" />
4 <ListView x:Name="PhotosListView"
5 ItemsSource="{Binding Photos}"
6 ItemTapped="OnItemTapped">
7 <ListView.ItemTemplate>
8 <DataTemplate>
9 <ImageCell ImageSource="{Binding Image}"
10 Text="{Binding Name}" />
11 </DataTemplate>
12 </ListView.ItemTemplate>
13 </ListView>
14 </StackLayout>

The ListView control binds its ItemsSource property to the Photos property on the MainPageViewModel class, which contains a series of photos and corresponding data. Each ListView item is an ImageCell control that displays the photo thumbnail and the photo name. For more information about the ListView control, including controlling the appearance of each item of data displayed by the control, see Working with ListView.

Navigating between pages

Xamarin.Forms provides a built-in navigation model that manages the navigation and user-experience of a stack of pages. This model implements a last-in, first-out stack of pages. For more information, see Navigation.

The XamarinPhotoViewer sample app triggers navigation requests from user interaction in the views. These requests are to navigate between the MainPage and PhotoPage views. When the user taps a ListView item on the MainPage, the PhotoPage is navigated to where the tapped item is displayed along with additional data. The wiring of the ItemTapped event to the OnItemTapped event handler in the view’s code-behind occurs in the view’s XAML.

1 public void OnItemTapped(object sender, ItemTappedEventArgs e)
2 {
3 var photo = e.Item;
4 if (photo == null)
5 return;
6
7 this.Navigation.PushAsync(new PhotoPage(photo));
8 this.PhotosListView.SelectedItem = null;
9 }

The OnItemTapped event handler retrieves the ListView item that was tapped on, and uses the Navigation.PushAsync method to open the PhotoPage, passing in the retrieved item which will be received by the PhotoPage view constructor and passed in turn into the PhotoPageViewModel constructor where it will be used to set view model properties that are bound to from the view. The event handler then resets the selected ListView item in preparation for navigation back to the MainPage view.

On the PhotoPage view, a Button control is used to return to the MainPage view. This Button invokes the OnBackButtonClicked event handler.

1 public void OnBackButtonClicked(object sender, EventArgs e)
2 {
3 this.Navigation.PopAsync();
4 }

This event handler uses the built-in back navigation provided by Xamarin.Forms to return to the previous page.

Summary

The MVVM pattern helps to cleanly separate the responsibility for the appearance and layout of the UI from the responsibility for the business logic. The main advantage of this approach is a reduction in the coupling between business logic and the UI which will make an app easier to test, maintain, and evolve.

The sample app can be downloaded here.

Monday, 22 December 2014

Encrypting and decrypting data in an Azure service using a certificate

I recently had a requirement to encrypt some data stored in a Web.config file for an Azure hosted service that’s accessed over HTTPS.

To help secure information in configuration files, ASP.NET provides a feature called protected configuration, which enables the encryption of sensitive data in a configuration file. The recommended approach is to protect configuration using either the DpapiProtectedConfigurationProvider class or the RsaProtectedConfigurationProvider class that are both included in the .NET framework.

Unfortunately these protected configuration providers do not work with Azure. The DpapiProtectedConfigurationProvider class uses a machine-specific key that cannot be transferred to Azure. While the RsaProtectedConfigurationProvider enables transferring an RSA key pair in an XML file to different machines, and then importing the key to a key container, the XML file is meant to be removed from the machine after the key has been imported. On Azure, since the account running the Web role doesn’t have permissions to delete files in the web root, it is not possible to remove the XML file.

I needed a solution that would:

  1. Allow data to be decrypted when running the service locally, and when running the service in Azure.
  2. Allow data to be encrypted and decrypted on any machine in our organization.
  3. Not be so onerous to prevent the periodic changing of the data to be encrypted/decrypted.

The recommended approach for Azure is to use the Pkcs12 custom protected configuration provider and the Aspnet_regiss.exe tool to encrypt sections of the configuration file. The Pkcs12 format enables transfer of certificates and their corresponding private keys from one machine to another. This provider is similar to the RsaProtectedConfigurationProvider, with the difference being that instead of transferring the RSA key pair in an XML file, it relies on the transfer to occur using a certificate in .PFX format. This approach has been used by P&P in the Autoscaling Application Block. While this provider works with the built-in tooling in ASP.NET that can read configuration automatically, it is an onerous solution for configuration that may change periodically.

This blog post details my solution, which was to use the SSL cert for the service to encrypt data once on a local machine, and then use the SSL certificate to decrypt data both locally and in Azure. The advantage of this approach is that for a service delivered over HTTPS, Azure will already have the SSL certificate stored in its certificate store, and so no additional key transfer is required.

Implementation

To encrypt a piece of data you must first retrieve the SSL certificate from its location in the certificate store, and then encrypt the data using the certificate. The following code example shows this process.

1 private static string Encrypt(string plainText)
2 {
3 // Thumb value for SSL cert
4 var thumb = "<thumbprint goes here>";
5
6 var passwordBytes = UTF8Encoding.UTF8.GetBytes(plainText);
7 var contentInfo = new ContentInfo(passwordBytes);
8 var env = new EnvelopedCms(contentInfo);
9 X509Store store = null;
10 string cipherText = null;
11
12 try
13 {
14 store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
15 store.Open(OpenFlags.ReadOnly);
16 var cert = store.Certificates.Cast<X509Certificate2>().Where(xc => xc.Thumbprint == thumb).Single();
17 env.Encrypt(new CmsRecipient(cert));
18
19 cipherText = Convert.ToBase64String(env.Encode());
20 }
21 finally
22 {
23 if (store != null)
24 store.Close();
25 }
26 return cipherText;
27 }

 


 

 

 

The X509Store class is used to provide access to the X.509 store, which is the physical store where certificates are persisted and managed. Once the store has been opened in read only mode, the SSL certificate is retrieved by searching for its thumbprint value. The data to be encrypted is stored in a CMS/PKCS #7 enveloped data structure, and is encrypted using the EnvelopedCms.Encrypt method. It’s then base64 encoded before being returned from the method.

Decrypting the data simply reverses the process. The same SSL certificate is retrieved from the certificate store, and then is used to decrypt the data. The following code example shows this process.

1 private static string Decrypt(string cipherText)
2 {
3 // Thumb value for SSL cert
4 var thumb = "<thumbprint goes here>";
5 X509Store store = null;
6 string plainText = null;
7
8 try
9 {
10 store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
11 store.Open(OpenFlags.ReadOnly);
12 var cert = store.Certificates.Cast<X509Certificate2>().Where(xc => xc.Thumbprint == thumb).Single();
13 var bytes = Convert.FromBase64String(cipherText);
14 var env = new EnvelopedCms();
15 env.Decode(bytes);
16 env.Decrypt();
17 plainText = Encoding.UTF8.GetString(env.ContentInfo.Content);
18 }
19 finally
20 {
21 if (store != null)
22 store.Close();
23 }
24 return plainText;
25 }

 

 

 

 

The X509Store class is used to provide access to the X.509 store, with the constructor taking arguments that indicate which part of the certificate store should be opened. Once the store has been opened in read only mode, the SSL certificate is retrieved by searching for its thumbprint value. The data to be decrypted is converted to a byte representation, from its base64 representation, before being decoded and decrypted by the EnvelopedCMS class. The plain text is then returned from the method.

This approach to encryption and decryption enables you to store sensitive information in your configuration file in an encrypted form, which can then be decrypted both when running the service locally, and when running it in Azure. It offers the advantage that it’s not necessary to transfer additional keys to Azure in order to perform decryption, and it’s not too onerous a task to change encrypted data periodically.  It can be further strengthened through the use of additional security techniques, including using the SecureString class at appropriate places in the code.

Summary

This blog post has demonstrated how to encrypt and decrypt data using an SSL cert. My requirement was to encrypt/decrypt data stored in a configuration file, but it may equally be used with other data. The advantage of this approach is that it enables you to decrypt data both when running a service locally, and when running it in Azure, without the onerous task of copying additional encryption key data to Azure.

Monday, 15 December 2014

Using basic authentication in an Azure Cloud Service

I recently had a requirement to use transport security with basic authentication in a web service hosted in Azure. Basic authentication is a mechanism for a HTTP user agent to provide credentials when making a request to the server, and is supported by all major browsers and servers. It doesn’t require cookies, session identifiers, or login pages. Instead it uses a static, standard HTTP header which means that no handshakes need to be performed.

IIS web servers provide basic authentication against Windows accounts on the server or through active directory. This situation is further complicated in services hosted in Azure. The following code shows how transport security with basic authentication can be specified in a web.config file.

1 <bindings>
2 <basicHttpsBinding>
3 <binding name="TransportSecurity">
4 <security mode="Transport">
5 <transport clientCredentialType="Basic"/>
6 </security>
7 </binding>
8 </basicHttpsBinding>
9 </bindings>

However, when you run an Azure cloud service with this configuration you’ll receive the following error message:

The authentication schemes configured on the host ('Anonymous') do not allow those configured on the binding 'BasicHttpsBinding' ('Basic').  Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly.  Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the <serviceAuthenticationManager> element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.

The initial problem is that basic authentication is unavailable by default for Azure web roles. It can be enabled either by enabling RDP on the virtual machine that the service is running on, RDPing in and adding basic authentication to IIS and then enabling it. Alternatively you could write a Powershell script to install basic authentication, and configure it to run from your VS solution when the web role starts up. Then you need to create a Windows account in the virtual machine that will be used during basic authentication.

This solution was not ideal. Moving forwards the service could have many different users, and I didn’t like the thought of having to create Windows accounts for each user. Furthermore, I’m a firm believer in trying to keep web services as provider agnostic as possible, in order to reduce problems if the service needs to be moved to another provider.

An alternative solution would be to use a different basic authentication module, provided by a third party. This is also not ideal, as it involves additional effort in identifying a suitable third party module to use, and then much time thoroughly testing it.

In this blog post I’ll outline my solution to this problem, which is to implement your own basic authentication mechanism. Basic authentication uses a simple protocol:

  1. The “username:password” format is used to combine username and password into one string.

  2. The resulting string is then base64 encoded.

  3. The encoding string is sent to the server in an Authorization header sent with the web request:
Authorization: Basic <base64 encoded username:password goes here>

Implementation

My solution is in three parts:

  1. Configure the service to use transport security but no authentication.
  2. In the service, intercept all web requests and parse out the Authorization header that contains the basic authentication credentials. The extracted credentials can then be compared against the actual credentials.
  3. In the client, intercept all web requests and add an appropriate Authorization header using the convention specified for basic authentication.

The following code shows how to configure the service to use transport security but not authentication.

1 <bindings>
2 <basicHttpsBinding>
3 <binding name="TransportSecurity">
4 <security mode="Transport">
5 <transport clientCredentialType="None"/>
6 </security>
7 </binding>
8 </basicHttpsBinding>
9 </bindings>

To intercept web requests to the service I created a class called BasicAuthenticationManager that derives from the ServiceAuthorizationManager class, which provides authorization access checking for service operations. This class overrides the CheckAccessCore method which checks authorization for the given operation context. In this method you can obtain the headers for the web request, and you can then parse out the Authorization header. The following code example shows this.

1 protected override bool CheckAccessCore(OperationContext operationContext)
2 {
3 var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
4
5 if (!string.IsNullOrWhiteSpace(authHeader))
6 {
7 if (authHeader.StartsWith("Basic"))
8 {
9 var credentials = ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(authHeader.Substring(6))).Split(':');
10
11 // Compare credentials against stored encrypted credentials
12 // If equal return true, otherwise false
13 }
14 }
15 }

The logic is straight forward: The Authorization header is extracted from the web request, and then the credentials are extracted from the Authorization header. The credentials can then be validated using your chosen approach (such as comparing them against encrypted credentials stored in configuration). If the credentials are valid, then return true. Otherwise return false, or throw the exception of your choosing to prevent the service operation being executed.

The service must then be configured to use the BasicAuthenticationManager class. This can be accomplished by adding a serviceAuthorization element to your web.config. Note that the format for specifying the class is AssemblyNamespace.Classname, AssemblyNamespace.

1 <?xml version="1.0"?>
2 <configuration>
3
4 <system.serviceModel>
5 ...
6 <behaviors>
7 <serviceBehaviors>
8 <behavior>
9 ...
10 <serviceAuthorization serviceAuthorizationManagerType="FullyQualifiedTypeName, AssemblyName" />
11 ...
12 </behavior>
13 </serviceBehaviors>
14 </behaviors>
15 </system.serviceModel>
16
17
18 </configuration>

The client that invokes the web service must then be updated to create the Authorization header for every service operation. The following code example shows this.

1 using (var client = new Proxy.Client())
2 {
3 var userName = "<username goes here>";
4 var password = "<password goes here>";
5
6 // Create the authorization header
7 var httpRequestProperty = new HttpRequestMessageProperty();
8 httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " +
9 Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + password));
10
11 using (new OperationContextScope(client.InnerChannel))
12 {
13 // Add the authorization header to every outgoing message
14 OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
15
16 // Make web requests
17 }
18 }


 

The HttpRequestMessageProperty class is used to provide access to the HTTP request, with the Headers property providing access to the HTTP headers from the request. It’s then easy to add an Authorization header that comprises “Basic “ and the base64 encoded “username:password” string. The OperationContextScope class is then used to add the authorization header to every outgoing message.

Summary

This blog post has demonstrated how to use basic authentication in an Azure cloud service, without having to expose the underlying virtual machine that the service runs on, and without then having to undertake messy configuration of the virtual machine. It offers more flexibility than using ISS basic authentication, as you can specify the credentials in your service, instead of having to rely upon basic authentication against a Windows account.