0 Comments

One of my current projects is using SpecFlow for testing some complex security logic; there are lots of scenarios so the BDD style of testing is well suited to the problem. I wanted to use the same style of testing for some integration testing where the client is talking to my API but hit a problem of how/where to construct the container as even the client library uses dependency injection to construct itself.

A search quickly found SpecFlow.Autofac by Gaspar Nagy, which provides a plugin to allow AutoFac to be used as a container by SpecFlow. We are using Unity in this project so I used the code at at https://github.com/gasparnagy/SpecFlow.Autofac to create the equivalent project for Unity 4 with the inspiring name of SpecFlow.Unity Smile. I’m not going to explain dependency injection yet again, just a short note on how to use the plugin.

The basic steps to making this work are

  1. Install the NuGet package
  2. Configure the container for the plugin
  3. Adjust the SpecFlow config

Installing the package

First add the package from NuGet into your SpecFlow project

PM> Install-Package SpecFlow.Unity

Configuring the container

Unlike AutoFac, Unity doesn’t have builder methods without going to Unity extensions, and I didn’t want to impose a particular style of construction on consumers of the plugin, so I presume that you already have a way of constructing an appropriate container.

What we do need to do however is make this container available to SpecFlow and also add some additional registrations so that the step definitions are produced by Unity and have their dependencies resolved.  To do this, you need to create a static method in your SpecFlow project and annotate it with a ScenarioDependencies attribute – the plugin has code that will automatically locate this and perform the appropriate configuration in SpecFlow.

A typical method would look something like this…

public static class TestDependencies {

     [ScenarioDependencies]

     public static IUnityContainer CreateContainer()

     {

         // create container with the runtime dependencies

         var container = Dependencies.CreateContainer();

 

         // TODO: add customizations, stubs required for testing

 

         // Registers the build steps, this gives us dependency resolution using the container.

         // NB If you need named parameters into the steps you should override specific registrations

         container.RegisterTypes(typeof(TestDependencies).Assembly.GetTypes().Where(t => Attribute.IsDefined(t, typeof(BindingAttribute))),

                                 WithMappings.FromMatchingInterface,

                                 WithName.Default,

                                 WithLifetime.ContainerControlled);

         return container;

     } }

To register the steps I’ve provided a little extension method in the plugin that does wraps this so instead you can do

container.RegisterStepDefinitions<StepClass>();

One other point is that if you need named dependencies injected into your steps you will have to re-register the step and give the dependencies explicitly. Also you must also have at least one step definition in the same assembly as the ScenarioDependencies method for the it to be found.

SpecFlow Config

The final step is to adjust your SpecFlow config file so that it knows you are using the plugin

    <specFlow>

         <!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config –>

         <unitTestProvider name="NUnit" />

         <runtime stopAtFirstError="false" missingOrPendingStepsOutcome="Inconclusive" />

         <stepAssemblies>

             <stepAssembly assembly="StepAssembly" />

         </stepAssemblies>

         <plugins>

             <add name="SpecFlow.Unity" type="Runtime" />

         </plugins>

     </specFlow>

There’s a full sample project at https://github.com/phatcher/SpecFlow.Unity/tree/master/sample/MyCalculator

Now you have a configured container and steps which are using dependency injection. Finally let me know how you get on at https://github.com/phatcher/SpecFlow.Unity and if there’s any demand for a version for Unity 3.5.

0 Comments

Couple of changes released today, one to Meerkat.Security and the other to Meerkat.Caching.

The first was to introduce handling for grant/deny of actions for unauthenticated users. I’d missed this use case before as to date, the project was just used in a corporate Windows environment and so everyone was authenticated by the time we saw them.

As I’m now working on a project using Azure B2C Active Directory we are now back to the point where users need to authenticate, so you want to filter the actions they can see/perform before and after they authenticate, e.g. you want to allow unauthenticated users access to Home.Index and error pages but probably not much more, and as the principle of the project was to centralize the security checking, we need a way to allow unauthenticated users without using AllowAnonymous on the controller action.

This lead to discovering a bug in Meerkat.Caching, where we tried to store a null in the cache and the underlying implementation, MemoryObjectCache, throws an exception in this case.  The fix was to trap the nulls and to ignore attempts to persist null to cache; don’t want to have to check on every call to the cache that we don’t have a null!

0 Comments

I’m working on a project where we are using Azure B2C Active Directory to provide authentication so that we can avoid the security headaches associated with managing a password store for it.

Unfortunately, the current implementation doesn’t support .NET Windows applications or standalone services where no user-interface is present – it will eventually, but I can’t wait on the eventual delivery date for these two use-cases.  I don’t want to re-introduce user name/password for this, as I’d introduce the same security issues that I was trying to avoid in the first place, but following a bit of research I decided the way forward was HMAC authentication.

I did have a look around the net, but I couldn’t find an implementation that had a NuGet package and was fully tested, so I wrote my own based on the code here

The flow from the client side looks like this..

  1. Retrieve your client id and secret from where you are keeping it on the client
  2. Produce a message representation
  3. Hash it with the secret
  4. Send the message

Server side, the flow is…

  1. Check if the message is HMAC authorized, if not ignore it
  2. Check if the message is within time e.g. +/- 5 minutes to allow for clock skew between client and server
  3. Retrieve the client id header and use that to locate the secret
  4. Check the MD5 hash of the content.
  5. Produce a message representation
  6. Hash it with the secret
  7. Check against the header hash If they match, check if we’ve seen if before, if so reject otherwise accept – this handles reply attacks

As this is intended to be production quality code, I’ve constructed the framework with interfaces so that each of the steps are replaceable or extensible from the default implementation.

So the key interfaces are -

  • ISecretRepository - Repository for client secrets.
  • IMessageRepresentationBuilder - Responsible for constructing a canonical representation of a message.
  • ISignatureCalculator- Calculates a message signature
  • ISignatureValidator – Validates a message signature

ISecretRepository will vary widely for each implementation as server-side you will most likely being picking this up from your database but on the client you might just acquire it from a config file or secure storage etc, so there’s only a trivial implementation included in the library which uses a ConcurrentDictionary.

Message Representation

How we construct the message representation is slightly different other implementations that I’ve seen.

/// <summary>
/// Builds a canonical representation of the request messsage.
/// </summary>
public class MessageRepresentationBuilder : IMessageRepresentationBuilder
{     private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);     private readonly List<Func<HttpRequestMessage, string>> headers;     /// <summary>     /// Construct a new instance of the <see cref="MessageRepresentationBuilder"/> class.     /// </summary>     public MessageRepresentationBuilder()     {         // Function order matches required order in representation         headers = new List<Func<HttpRequestMessage, string>>         {             // NB Needed as the server-side request uri has been escaped e.g. /odata/%24metadata             // Also different .NET libraries encode differently - see http://stackoverflow.com/questions/575440/url-encoding-using-c-sharp/21771206#21771206             m => WebUtility.UrlDecode(m.RequestUri.AbsolutePath.ToLower()),             m => m.Method.Method,             m => m.Content.Md5Base64(),             m => m.Headers.MessageDate(),             m => m.Headers.GetFirstOrDefaultValue<string>(HmacAuthentication.ClientIdHeader),             m => m.Headers.CustomHeadersRepresentation(HmacAuthentication.CustomHeaders),         };     }     /// <summary>     /// Builds message representation as follows:     /// HTTPMethod\n +     /// Request URI\n +     /// Content-MD5\n +       /// Timestamp\n +     /// Username\n +     /// Custom Headers (x-msec-headers values)     /// </summary>     /// <returns></returns>     public string BuildRequestRepresentation(HttpRequestMessage requestMessage)     {         var values = new List<string>();         foreach (var gm in headers)         {             var value = gm(requestMessage);             if (value == null)             {                 // Fail on first null                 return null;             }             values.Add(value);         }         var result = string.Join("\n", values);         Logger.DebugFormat("Representation: {0}", result);         return result;     }
}

For the server to rely on the information in the message, it needs to be part of hash, otherwise some party can replace that part of the message and replay the message and the server won’t know that there’s an issue.

All of the content is already handled by the hash, so we need some generic way of saying we want to include other message headers as part of the signature calculation and that’s where the “x-msec-headers” header is used. It is a header containing the names of other headers that need to be included in the hash, for example a nonce value so that every request issued from a client is unique.

The nice thing about this is that the server implementation does not need to care – all of the information is held in the message itself; this idea is used to secure the Amazon Simple Storage APIs, which is where I got the idea from.

Signature Calculation

The next step is calculating the signature

/// <summary>
/// Computes a HMAC signature.
/// </summary>
public class HmacSignatureCalculator : ISignatureCalculator
{     private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);     // TODO: Inject this via either constructor      private const string HmacScheme = "SHA256";     /// <copydoc cref="ISignatureCalculator.Signature" />     public string Signature(string secret, string value)     {         if (Logger.IsDebugEnabled)         {             Logger.DebugFormat("Source {0}: '{1}'", secret.Substring(0, 2) + "...", value);         }         var secretBytes = Encoding.Unicode.GetBytes(secret);         var valueBytes = Encoding.Unicode.GetBytes(value);         string signature;         if (Logger.IsDebugEnabled)         {             Logger.DebugFormat("Value '{0}'", BitConverter.ToString(valueBytes));         }                 using (var hmac = HmacProvider(secretBytes, HmacScheme))         {             var hash = hmac.ComputeHash(valueBytes);             signature = Convert.ToBase64String(hash);         }         if (Logger.IsDebugEnabled)         {             Logger.DebugFormat("Signature {0} : {1}", HmacScheme, signature);         }         return signature;     }     private HMAC HmacProvider(byte[] secret, string value)     {         switch (value)         {             case "MD5":             case "SHA1":                 throw new NotSupportedException(string.Format("Hash '{0}' is not secure and is not supported", value));             case "SHA384":                 return new HMACSHA384(secret);             case "SHA512":                 return new HMACSHA512(secret);             default:                 return new HMACSHA256(secret);         }     }
}

So this allows us to change the encryption algorithm without affecting the rest of the system, bear in mind it wasn’t that long ago when SHA-1 and MD-5 were acceptable ways of computing a one way hash.

Signature Validation

The final part server side is validating the signature

/// <summary>
/// Validates a HMAC signature if present.
/// </summary>
public class HmacSignatureValidator : ISignatureValidator
{     private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);     private const string CacheRegion = "hmac";     private readonly ISignatureCalculator signatureCalculator;     private readonly IMessageRepresentationBuilder representationBuilder;     private readonly ISecretRepository secretRepository;     private readonly ICache objectCache;     /// <summary>     /// Creates a new instance of the <see cref="HmacSignatureValidator"/> class.     /// </summary>     /// <param name="signatureCalculator"></param>     /// <param name="representationBuilder"></param>     /// <param name="secretRepository"></param>     /// <param name="objectCache"></param>     /// <param name="validityPeriod"></param>     public HmacSignatureValidator(ISignatureCalculator signatureCalculator,          IMessageRepresentationBuilder representationBuilder,         ISecretRepository secretRepository,         ICache objectCache,         int validityPeriod)     {         this.secretRepository = secretRepository;         this.representationBuilder = representationBuilder;         this.signatureCalculator = signatureCalculator;         this.objectCache = objectCache;         ValidityPeriod = validityPeriod;     }     /// <summary>     /// Gets the validity period of a signature in minutes, used to allow for clock-drift between client and server     /// and also to avoid replay attacks     /// </summary>     public int ValidityPeriod { get; }     /// <summary>     /// Validates whether we are using HMAC and if so is the signature valid.     /// </summary>     /// <param name="request"></param>     /// <returns></returns>     public async Task<bool> IsValid(HttpRequestMessage request)     {         // TODO: Generalize so we can using any HMAC scheme.         if (request.Headers.Authorization == null || request.Headers.Authorization.Scheme != HmacAuthentication.AuthenticationScheme)         {             // No authorization or not our authorization schema, so no              Logger.DebugFormat("Not our authorization schema: {0}", request.RequestUri);             return false;         }         var isDateValid = request.IsMessageDateValid(ValidityPeriod);         if (!isDateValid)         {             // Date is not present or valid             Logger.DebugFormat("Invalid date: {0}", request.RequestUri);             return false;         }         var userName = request.Headers.GetFirstOrDefaultValue<string>(HmacAuthentication.ClientIdHeader);         if (string.IsNullOrEmpty(userName))         {             // No user name             Logger.DebugFormat("No client id: {0}", request.RequestUri);             return false;         }         var secret = secretRepository.ClientSecret(userName);         if (secret == null)         {             // Can't find a secret for the user, so no             Logger.DebugFormat("No secret for client id {0}: {1}", userName, request.RequestUri);             return false;         }         if (!await request.Content.IsMd5Valid())         {             // MD5 is invalid, so no             Logger.DebugFormat("Invalid MD5 hash: {0}", request.RequestUri);             return false;         }         // Construct the representation         var representation = representationBuilder.BuildRequestRepresentation(request);         if (representation == null)         {             // Something broken in the representation, so no             Logger.DebugFormat("Invalid canonical representation: {0}", request.RequestUri);             return false;         }         // Compute the signature         // TODO: Pass the encryption algorithm used e.g. SHA256         var signature = signatureCalculator.Signature(secret, representation);         // Have we seen it before         if (objectCache.Contains(signature))         {             // Already seen, so no to avoid replay attack             Logger.WarnFormat("Request replayed {0}: {1}", signature, request.RequestUri);             return false;         }         // Validate the signature         var result = request.Headers.Authorization.Parameter == signature;         if (result)         {             // Store valid signatures to avoid replay attack             objectCache.Set(signature, userName, DateTimeOffset.UtcNow.AddMinutes(ValidityPeriod), CacheRegion);         }         // Return the signature validation.         return result;     }
}

Note that we log failures for debugging purposes but don’t return that information back to the caller – they get a simple pass/fail to avoid exposing information to a potential attacker.

In part 2 I’ll cover off how to use these to secure a WebApi controller, how to wire up the various components and how a client application might look.

There are a couple of points to remember with HMAC

  • You still have a key distribution problem, how are you going to assign the client id/secret pairs
  • You should not use the client id for authorization, just authentication to make life easier when you invalidate the client id and/or assign multiple ids to the same user.

Bibliography

Here are the various implementations I found around the net.

HMAC Authentication in Asp.Net Web API – this was my starting point (link seems to be down but article is also here)

Secure ASP.NET WebAPI authentication using API Key Authentication - HMAC Authentication – Taiseer Joudeh

Learn to Secure an ASP.NET Web API using HMAC – Arun Karthick

How to secure an ASP.NET Web API – Stackoverflow.

0 Comments

With unit testing one of the precepts is to check one thing in your test, but when you have objects this is difficult to express, since you want to check that the your business process has updated all of the expected properties (positive testing) and also that has not modified things that are not expected to have changed (negative testing).

This becomes even more problematic when you have an object graph, e.g. Order –> OrderLine –> Product where you have to navigate the graph, and reporting accurately where any errors is also a major issue as you need to track property names, collection indexes, etc. etc.

I wrote something to help me a few years ago and due to the nagging nudging of a colleague (I’m looking at you Rob Bagby), I’ve finally reformed it into something that’s hopefully useable by everyone else, called NCheck.

What this allows you to do is compare objects and the library will do a property by property comparison for you, handling collection properties and other referenced entities. What is nice I think, is that you still have control over what properties are included in the comparison and there are helpers for breaking object cycles using the your domain’s concept of identity.

Here’s a short introduction, given a simple class

public class Simple
{
    public int Id { get; set; }

    public string Name { get; set; }

    public double Value { get; set; }
}

we would like to test what happens after running some business service over it, we can do this easily with an NUnit test


[TestFixture]
public class SimpleTest
{
    [Test]
    public void AlgoTest()
    {
        var algo = new ShinyBusinssService();
        var source = new Simple { Id = 1, Name = "A", Value = 1.0 } ;

        var candidate = algo.Run(source);
        Assert.AreEqual(2, candidate.Id, "Id differs");
        Assert.AreEqual("B", candidate.Name, "Name differs");
        Assert.AreEqual(1.2, candidate.Value, "Value differs");
    }
}

If we re-write this using NCheck we get

[TestFixture]
public class SimpleTest
{
    [Test]
    public void AlgoTest()
    {
        var checkerFactory = new CheckerFactory();

        var algo = new ShinyBusinessService();
        var source = new Simple { Id = 1, Name = "A", Value = 1.0 } ;

        var expected = new Simple { Id = 2, Name = "B", Value = 1.2 } ;

        var candidate = algo.Run(source);
        checkerFactory.Check(expected, candidate);
    }
}

Behind the scenes, the CheckFactory class has created a comparison checker (using reflection) to compare each property of the Simple class, but you can also explicitly create a Checker<T> class if you want complete control.

The library is available as a NuGet package and the source code is on GitHub

0 Comments

A number of years ago Sebasiten Lorion wrote a very good CSV parser for .NET with the code and an accompanying article on Code Project -  A Fast CSV Reader.  I’d used this in a number of projects but recently I needed to make some changes to the code for my trading system project, and there wasn’t a public repository available; there’s a version on NuGet but it doesn’t point back to the source.

As the project is under the MIT Licence, I did the next best thing and made my own repository on GitHub – CsvReader and there’s a NuGet package as well