Basic Token Service for WCF Services (Part 3 – Token Validation in IDispatchMessageInspector)

In Basic Token Service for WCF Services (Part 2 – Database Authentication) we showed how to verify our token. However, we verified the token in the service itself.

WCF BTS Message Inspector

This is not ideal.

    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
    public string Test()
    {
        var token = HttpContext.Current.Request.Headers["Token"];
        using (var dbContext = new BasicTokenDbContext())
        {
            ITokenValidator validator = new DatabaseTokenValidator(dbContext);
            if (validator.IsValid(token))
            {
                // Do service work here . . . 
            }
        }
    }

This is fine for a one or two services. But what if there are going to have many services? The Don’t Repeat Yourself (DRY) principle would be broken if we repeated the same lines of code at the top of every service. If only we could validate the token in one place, right? Well, we can.

We could make a method that we could call at the top of every service, but even if we did that, we would still have to repeat one line for every service. Is there a way where we wouldn’t even have to repeat a single line of code? Yes, there is. Using Aspect-oriented programming (AOP). It turns out WCF services have some AOP capabilities built in.

IDispatchMessageInspector can be configured to do this.

To enable this, your really need to implement three Interfaces and configure it in the web.config. I am going to use separate classes for each interface.

The web config extension class:

using System;
using System.ServiceModel.Configuration;

namespace WcfSimpleTokenExample.Behaviors
{
    public class TokenValidationBehaviorExtension : BehaviorExtensionElement
    {
        #region BehaviorExtensionElement

        public override Type BehaviorType
        {
            get { return typeof(TokenValidationServiceBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new TokenValidationServiceBehavior();
        }

        #endregion
    }
}

The Service Behavior class:

using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace WcfSimpleTokenExample.Behaviors
{
    public class TokenValidationServiceBehavior : IServiceBehavior
    {
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (var t in serviceHostBase.ChannelDispatchers)
            {
                var channelDispatcher = t as ChannelDispatcher;
                if (channelDispatcher != null)
                {
                    foreach (var endpointDispatcher in channelDispatcher.Endpoints)
                    {
                        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new TokenValidationInspector());
                    }
                }
            }
        }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }
    }
}

The message inspector class

using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using WcfSimpleTokenExample.Business;
using WcfSimpleTokenExample.Database;
using WcfSimpleTokenExample.Interfaces;

namespace WcfSimpleTokenExample.Behaviors
{
    public class TokenValidationInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            // Return BadRequest if request is null
            if (WebOperationContext.Current == null) { throw new WebFaultException(HttpStatusCode.BadRequest); }

            // Get Token from header
            var token = WebOperationContext.Current.IncomingRequest.Headers["Token"];

            // Validate the Token
            using (var dbContext = new BasicTokenDbContext())
            {
                ITokenValidator validator = new DatabaseTokenValidator(dbContext);
                if (!validator.IsValid(token))
                {
                    throw new WebFaultException(HttpStatusCode.Forbidden);
                }
                // Add User ids to the header so the service has them if needed
                WebOperationContext.Current.IncomingRequest.Headers.Add("User", validator.Token.User.Username);
                WebOperationContext.Current.IncomingRequest.Headers.Add("UserId", validator.Token.User.Id.ToString());
            }
            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
        }
    }
}

Basically, what happens is AfterReceiveRequest is called somewhere between when the actual packets arrive at the server and just before the service is called. This is perfect. We can validate our token here in a single place.

So let’s populate our AfterReceiveRequest.

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            // Return BadRequest if request is null
            if (WebOperationContext.Current == null) { throw new WebFaultException(HttpStatusCode.BadRequest); }

            // Get Token from header
            var token = WebOperationContext.Current.IncomingRequest.Headers["Token"];

            // Validate the Token
            using (var dbContext = new BasicTokenDbContext())
            {
                ITokenValidator validator = new DatabaseTokenValidator(dbContext);
                if (!validator.IsValid(token))
                {
                    throw new WebFaultException(HttpStatusCode.Forbidden);
                }
                // Add User ids to the header so the service has them if needed
                WebOperationContext.Current.IncomingRequest.Headers.Add("User", validator.Token.User.Username);
                WebOperationContext.Current.IncomingRequest.Headers.Add("UserId", validator.Token.User.Id.ToString());
            }
            return null;
        }

You might have noticed we made one change to the ITokenValidator. See the changes below. It now has a Token property, as does its implementation, DatabaseTokenValidator. Mostly I am getting Token.UserId, but since EF gets the User object for me too, I went ahead an added the User name as well.

using WcfSimpleTokenExample.Database;
namespace WcfSimpleTokenExample.Interfaces
{
    public interface ITokenValidator
    {
        bool IsValid(string token);
        Token Token { get; set; }
    }
}
using System;
using System.Linq;
using WcfSimpleTokenExample.Database;
using WcfSimpleTokenExample.Interfaces;

namespace WcfSimpleTokenExample.Business
{
    public class DatabaseTokenValidator : ITokenValidator
    {
        // Todo: Set this from a web.config appSettting value
        public static double DefaultSecondsUntilTokenExpires = 1800;

        private readonly BasicTokenDbContext _DbContext;

        public DatabaseTokenValidator(BasicTokenDbContext dbContext)
        {
            _DbContext = dbContext;
        }

        public bool IsValid(string tokentext)
        {
            Token = _DbContext.Tokens.SingleOrDefault(t => t.Text == tokentext);
            return Token != null && !IsExpired(Token);
        }

        internal bool IsExpired(Token token)
        {
            var span = DateTime.Now - token.CreateDate;
            return span.TotalSeconds > DefaultSecondsUntilTokenExpires;
        }

        public Token Token { get; set; }
    }
}

Now we don’t need all that Token validation code in our Service. We can clean it up. In fact, since all it does right now is return a string, our service only needs a single line of code. I also added the UserId and User to the output for fun.

    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Test1Service
    {
        [OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        public string Test()
        {
            return string.Format("Your token worked! User: {0} User Id: {1}",
                WebOperationContext.Current.IncomingRequest.Headers["UserId"],
                WebOperationContext.Current.IncomingRequest.Headers["User"]);
        }
    }

Well, now that it is all coded up, it won’t work until we enable the new behavior in the web.config. So let’s look at the new web.config. We create a new ServiceBehavior (lines 34-38) for all the services that validate the token. We leave the AuthenticationTokenService the same as we don’t have a token when we hit it because we hit it to get the token. We also need to make sure to add the behavior extension (lines 41-46). Then we need to tell our ServiceBehavior to use the new extension (line 37).

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfSimpleTokenExample.Services.AuthenticationTokenService" behaviorConfiguration="ServiceBehaviorHttp">
        <endpoint address="" behaviorConfiguration="AjaxEnabledBehavior" binding="webHttpBinding" contract="WcfSimpleTokenExample.Services.AuthenticationTokenService" />
      </service>
      <service name="WcfSimpleTokenExample.Services.Test1Service" behaviorConfiguration="ServiceAuthBehaviorHttp">
        <endpoint address="" behaviorConfiguration="AjaxEnabledBehavior" binding="webHttpBinding" contract="WcfSimpleTokenExample.Services.Test1Service" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="AjaxEnabledBehavior">
          <webHttp helpEnabled="true" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviorHttp">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <behavior name="ServiceAuthBehaviorHttp">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <TokenValidationBehaviorExtension />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add name="TokenValidationBehaviorExtension"
          type="WcfSimpleTokenExample.Behaviors.TokenValidationBehaviorExtension, WcfSimpleTokenExample, Version=1.0.0.0, Culture=neutral"/>
      </behaviorExtensions>
    </extensions>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <directoryBrowse enabled="true" />
  </system.webServer>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <connectionStrings>
    <add name="BasicTokenDbConnection" connectionString="data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\BasicTokenDatabase.mdf;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

AOP Custom Contract: ListNotEmptyAttribute

So I have a List and I need to make sure that the list has at least one value when it is passed in. If the list is empty, I should throw and exception. Here is an example of what the code would look like if you did NOT use an aspect:

using System;
using System.Collections.Generic;

namespace CustomContractsExample
{
    public class People
    {
        private readonly List<Person> _People;

        public People(List<Person> people)
        {
            if (people == null)
                throw new ArgumentNullException("people", "The list cannot be null.");
            if (people.Count == 0)
                throw new ArgumentException("people", "The list cannot be empty.");
            _People = people;
        }

        public List<Person> List
        {
            get { return _People; }
        }
    }
}

Note: My use case is not actually a People object with a List. It is instead something proprietary for my company and a far more valid use case. I am using the People class for simplicity in demonstration only.

I decided to handle this precondition checking not in the methods, but in an Aspect. Particularly, by using a PostSharp LocationContractAttribute. I recently wrote a post about this here:
AOP Contracts with PostSharp

So we need to create a new custom contract as I didn’t find one written by PostSharp. At first, I wondered why not. Why not create a quick generic attribute like this:

using System.Collections.Generic;
using PostSharp.Aspects;
using PostSharp.Patterns.Contracts;
using PostSharp.Reflection;

namespace CustomContractsExample
{
    public class ListNotEmptyAttribute<T> : LocationContractAttribute, ILocationValidationAspect<List<T>>
    {
        new public const string ErrorMessage = "The List<T> must not be empty.";

        protected override string GetErrorMessage()
        {
            return "The List<T> must not be empty: {2}";
        }

        public System.Exception ValidateValue(List<T> value, string locationName, LocationKind locationKind)
        {
            if (value == null)
                return CreateArgumentNullException(value, locationName, locationKind);
            if (value.Count == 0)
                return CreateArgumentException(value, locationName, locationKind);
            return null;
        }
    }
}

Well, the reason is because C# doesn’t support generic attributes. I get this error at compile time:

A generic type cannot derive from ‘LocationContractAttribute’ because it is an attribute class

This is a tragedy. What makes it more of a tragedy is that I could do this if I wrote directly in IL. It is simply a compiler limitation for C#. Arrrgggss!!!! Good thing MSBuild is going open source at https://github.com/Microsoft/msbuild. Hopefully, the DotNet team, or some interested party such as PostSharp, or maybe me, contributes a few changes to MSBuild and removes this limitation.

As for now, List also implements IList, so I will revert to using that. IList provided a workaround for this use case, however, such a work around won’t always be available.

using System.Collections;
using PostSharp.Aspects;
using PostSharp.Patterns.Contracts;
using PostSharp.Reflection;

namespace CustomContractsExample
{
    public class ListNotEmptyAttribute : LocationContractAttribute, ILocationValidationAspect<IList>
    {
        new public const string ErrorMessage = "The List must not be empty.";

        protected override string GetErrorMessage()
        {
            return "The list must not be empty: {2}";
        }

        public System.Exception ValidateValue(IList value, string locationName, LocationKind locationKind)
        {
            if (value == null)
                return CreateArgumentNullException(value, locationName, locationKind);
            if (value.Count == 0)
                return CreateArgumentException(value, locationName, locationKind);
            return null;
        }
    }
}

Now here is the new People class. See how it is much cleaner.

using System.Collections.Generic;

namespace CustomContractsExample
{
    public class People
    {
        private readonly List<Person> _People;

        public People([ListNotEmpty]List<Person> people)
        {
            _People = people;
        }

        public List<Person> List
        {
            get { return _People; }
        }
    }
}

The constructor is much cleaner and easier to read.

Also, my unit tests pass.

using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CustomContractsExample;

namespace CustomContractsExampleTests
{
    [TestClass]
    public class PeopleTests
    {
        // Arrange
        private const string Firstname = "Jared";
        private const string LastName = "Barneck";

        [TestMethod]
        public void TestNewPersonWorks()
        {
            var person = new Person(Firstname, LastName);
            var list = new List<Person> { person };
            var people = new People(list);

            Assert.IsNotNull(people);
            Assert.IsFalse(people.List.Count == 0);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestNewPersonThrowsExceptionIfFirstNameNull()
        {
            new People(null);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestNewPersonThrowsExceptionIfLastNameNull()
        {
            new People(new List<Person>());
        }
    }
}

Maybe PostSharp can pick this up my ListNotEmptyAttribute and add it to their next released version.


AOP Contracts with PostSharp

So, I’ve been using Aspect Oriented Programming for a while. My company has a license for PostSharp. Recently I started using it more, in particularly, I started using the Contracts feature for checking the parameters of my methods. This is called precondition checking. Read more here: PostSharp Contracts

Here is a basic example of precondition checking. Imagine a Person class where the firstName and lastName should throw an exception if null, empty, or whitespace.
Your code might look like this:

using System;

namespace CustomContractsExample
{
    public class Person
    {
        private readonly string _FirstName;
        private readonly string _LastName;

        public Person(string firstName, string lastName)
        {
            // Validate first name
            if (string.IsNullOrWhiteSpace(firstName))
                throw new ArgumentException("Parameter cannot be a null, empty or whitespace string.", "firstName");

            // Validate last name
            if (lastName == string.Empty)
                throw new ArgumentException("Parameter cannot be an null, empty or whitespace string.", "lastName");

            // Initialize fields
            _FirstName = firstName;
            _LastName = lastName;
        }

        public string FirstName
        {
            get { return _FirstName; }
        }

        public string LastName
        {
            get { return _LastName; }
        }
    }
}

Ugh! Those lines to validate and throw exceptions are UGLY! Not to mention redundant. How many times might you write this same code. Probably over and over again. Of course this breaks the Don’t Repeat Yourself (DRY) principle.

Now, install PostSharp.Patterns.Model from NuGet.
(Note 1: This also installs PostSharp and PostSharp.Patterns.Common.)
(Note 2: This requires a paid license but is well worth it).

Looking at the Contracts, we particularly are interested in this one:

RequiredAttribute

RequiredAttribute is an attribute that, when added to a field, property or parameter, throws an ArgumentNullException if the target is assigned a null value or an empty or white-space string.

Here is the same class using PostSharp.Aspects.Contracts.

using PostSharp.Patterns.Contracts;

namespace CustomContractsExample
{
    public class Person
    {
        private readonly string _FirstName;
        private readonly string _LastName;

        public Person([Required]string firstName, [Required]string lastName)
        {
            _FirstName = firstName;
            _LastName = lastName;
        }

        public string FirstName
        {
            get { return _FirstName; }
        }

        public string LastName
        {
            get { return _LastName; }
        }
    }
}

Now, doesn’t that looks much nicer.

Yes, it does.

One issue:

It throws an ArgumentNullException if the string is empty or WhiteSpace. To me this is “Ok” but not preferred. If the data is not null, we shouldn’t say it is. Looking at the RequiredAttribute code, it is doing this:

        public Exception ValidateValue(string value, string locationName, LocationKind locationKind)
        {
            if (!string.IsNullOrWhiteSpace(value))
                return null;
            return CreateArgumentNullException(value, locationName, locationKind);
        }

It really should be doing this.

        public Exception ValidateValue(string value, string locationName, LocationKind locationKind)
        {
            if (value == null)
                return (Exception)this.CreateArgumentNullException((object)value, locationName, locationKind);
            if (string.IsNullOrWhiteSpace(value))
                return (Exception)this.CreateArgumentException((object)value, locationName, locationKind);
            return (Exception)null;
        }

We can easily roll our own class to fix this bug.

using System;
using PostSharp.Aspects;
using PostSharp.Patterns.Contracts;
using PostSharp.Reflection;

namespace CustomContractsExample
{
    public sealed class StringRequiredAttribute : LocationContractAttribute, ILocationValidationAspect<string>
    {
        protected override string GetErrorMessage()
        {
            return (ContractLocalizedTextProvider.Current).GetMessage("RequiredErrorMessage");
        }

        public Exception ValidateValue(string value, string locationName, LocationKind locationKind)
        {
            if (value == null)
                return CreateArgumentNullException(value, locationName, locationKind);
            if (string.IsNullOrWhiteSpace(value))
                return CreateArgumentException(value, locationName, locationKind);
            return null;
        }
    }
}

And here are my unit tests for what I expect. They all pass with my new StringRequired class.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CustomContractsExample;

namespace CustomContractsExampleTests
{
    [TestClass]
    public class PersonTests
    {
        // Arrange
        private const string Firstname = "Jared";
        private const string LastName = "Barneck";

        [TestMethod]
        public void TestNewPersonWorks()
        {
            var person = new Person(Firstname, LastName);
            Assert.IsNotNull(person);
            Assert.IsFalse(string.IsNullOrWhiteSpace(person.FirstName));
            Assert.IsFalse(string.IsNullOrWhiteSpace(person.LastName));
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestNewPersonThrowsExceptionIfFirstNameNull()
        {
            new Person(null, LastName);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestNewPersonThrowsExceptionIfLastNameNull()
        {
            new Person(Firstname, null);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestNewPersonThrowsExceptionIfFirstNameEmpty()
        {
            new Person(string.Empty, LastName);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestNewPersonThrowsExceptionIfLastNameEmpty()
        {
            new Person(Firstname, "");
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestNewPersonThrowsExceptionIfFirstNameWhiteSpace()
        {
            new Person("  ", LastName);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestNewPersonThrowsExceptionIfLastNameWhiteSpace()
        {
            new Person(Firstname, "     ");
        }
    }
}

How to mock an Entity Framework DbContext and its DbSet properties

Entity Framework (EF) is a data access layer (DAL) that allows for easily accessing a database for your create, read, update, and delete (CRUD) actions. If you use Entity Framework, you don’t need to test your DAL CRUD actions. You just need to test your code that uses it.

With EF, you can mock your database, though it isn’t exactly easy. The database is interfaced through the DbContext. Tables are interfaces through property of type DbSet where T is an object representing data in table. For example DbSet would represent your users. We can use a List to mock the database table. It would also be nice if we could easily have every table mocked by default.

Ok, now that we have established that EF 6 DbContext mocking isn’t easy, let’s change that. Let’s make it easy.

Using the following two classes, you can easily mock your DbContext with a single line of code:

MockDbContext = EntityFrameworkMockHelper.GetMockContext<MyDbContext>();
[/chsarp]

Note: While this single line of code successfully mocks your DbContext, it doesn't add any default data. You still have to do that work yourself, but now it should be easy, because you can use the very easy to use Add method on any table. 

1
MockDbContext.Object.People.Add(new Person{ FirstName = "John", LastName = "Doe" });

Or if you have a List of sample data already created, you can add that list with AddRange.

MockDbContext.Object.People.AddRange(SamplePeople);

And here are the two classes I wrote to help with this. I must admit, I spent over three days researching this and getting this working. So hopefully this saves you from having to do the same.

using Moq;
using System.Collections.Generic;
using System.Data.Entity;

namespace LANDesk.Licensing.WebServices.Tests.Data
{
    public class MockedDbContext<T> : Mock<T> where T : DbContext
    {
        public Dictionary<string, object> Tables
        {
            get { return _Tables ?? (_Tables = new Dictionary<string, object>()); }
        } private Dictionary<string, object> _Tables;
    }
}
using System;
using Moq;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;

namespace LANDesk.Licensing.WebServices.Tests.Data
{
    public static class EntityFrameworkMockHelper
    {
        /// <summary>
        /// Returns a mock of a DbContext
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static MockedDbContext<T> GetMockContext<T>() where T : DbContext
        {
            var instance = new MockedDbContext<T>();
            instance.MockTables();
            return instance;
        }

        /// <summary>
        /// Use this method to mock a table, which is a DbSet{T} oject, in Entity Framework.
        /// Leave the second list null if no adds or deletes are used.
        /// </summary>
        /// <typeparam name="T">The table data type</typeparam>
        /// <param name="table">A List{T} that is being use to replace a database table.</param>
        /// <returns></returns>
        public static DbSet<T> MockDbSet<T>(List<T> table) where T : class
        {
            var dbSet = new Mock<DbSet<T>>();
            dbSet.As<IQueryable<T>>().Setup(q => q.Provider).Returns(() => table.AsQueryable().Provider);
            dbSet.As<IQueryable<T>>().Setup(q => q.Expression).Returns(() => table.AsQueryable().Expression);
            dbSet.As<IQueryable<T>>().Setup(q => q.ElementType).Returns(() => table.AsQueryable().ElementType);
            dbSet.As<IQueryable<T>>().Setup(q => q.GetEnumerator()).Returns(() => table.AsQueryable().GetEnumerator());
            dbSet.Setup(set => set.Add(It.IsAny<T>())).Callback<T>(table.Add);
            dbSet.Setup(set => set.AddRange(It.IsAny<IEnumerable<T>>())).Callback<IEnumerable<T>>(table.AddRange);
            dbSet.Setup(set => set.Remove(It.IsAny<T>())).Callback<T>(t => table.Remove(t));
            dbSet.Setup(set => set.RemoveRange(It.IsAny<IEnumerable<T>>())).Callback<IEnumerable<T>>(ts =>
            {
                foreach (var t in ts) { table.Remove(t); }
            });
            return dbSet.Object;
        }

        /// <summary>
        /// Mocks all the DbSet{T} properties that represent tables in a DbContext.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="mockedContext"></param>
        public static void MockTables<T>(this MockedDbContext<T> mockedContext) where T : DbContext
        {
            Type contextType = typeof(T);
            var dbSetProperties = contextType.GetProperties().Where(prop => (prop.PropertyType.IsGenericType) && prop.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>));
            foreach (var prop in dbSetProperties)
            {
                var dbSetGenericType = prop.PropertyType.GetGenericArguments()[0];
                Type listType = typeof(List<>).MakeGenericType(dbSetGenericType);
                var listForFakeTable = Activator.CreateInstance(listType);
                var parameter = Expression.Parameter(contextType);
                var body = Expression.PropertyOrField(parameter, prop.Name);
                var lambdaExpression = Expression.Lambda<Func<T, object>>(body, parameter);
                var method = typeof(EntityFrameworkMockHelper).GetMethod("MockDbSet").MakeGenericMethod(dbSetGenericType);
                mockedContext.Setup(lambdaExpression).Returns(method.Invoke(null, new[] { listForFakeTable }));
                mockedContext.Tables.Add(prop.Name, listForFakeTable);
            }
        }
    }
}

An Xml class to linearize xml, make pretty xml, and encoding in UTF-8 or UTF-16.

OK, so I had to output an Xml for something I am doing for work. I need the Xml to be pretty. I decided I wanted a C# class that would do the equivalent of what the Xml plugin in Notepad++ does. It should create Linear Xml, Pretty Xml, etc.

I found a bunch of problems when doing this in C#:

  1. How to make an Xml linearized in C#?
  2. How to make the Xml pretty, including indents and cleaned up spacing? I could get the indents, but the spacing was a problem until I solved how to linearize the Xml.
  3. How to make the Xml declaration say UTF-8? It kept saying the Xml was in UTF-16, which was accurate because the file was UTF-16. Strings in C# are always Unicode (UTF-16).
  4. How to make UTF-8 uppercase? Once I got the Xml declaration to say UTF-8, the UTF-8 text was lowercase, utf-8, instead of uppercase. Lowercase should work, but it turns out uppercase is preferred.
  5. How to output the Xml as a file in actual UTF-8 format? It is one thing to have UTF-8 in the Xml declaration, it is quite another to actually output a file byte stream in UTF-8 vs UTF-16 (Unicode). A UTF-8 file should be 1/2 the size of a UTF-16 file.

So here is my class. I hope it helps you. All the questions are answered by this class.

using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;

namespace LANDesk.Licensing.WebServices.Model
{
    public class Xml
    {
        public Xml(string text)
        {
            Text = text;
        }

        /// <summary>
        /// And enumeration to select UTF8 or UTF16 encoding. This is used because the defautl UTF8 
        /// and Unicode encoding types don't capitalize the UTF characters in the Xml declaration.
        /// </summary>
        public enum XmlEncoding
        {
            UTF8, // By being first it is the default
            UTF16
        };

        /// <summary>
        /// The original Xml text as is.
        /// </summary>
        public string Text { get; private set; }

        /// <summary>
        /// The Xml in a single line (no new lines or carriage returns). The data is trimmed and no more than a single space anywhere.
        /// </summary>
        public string LinearizeXml
        {
            get { return _LinearizeXml ?? (_LinearizeXml = Clean(Document, LinearizedSettings)); }
        } private string _LinearizeXml;

        /// <summary>
        /// And XDocument representation of the Xml. It uses the Linearized Xml not the original text.
        /// </summary>
        public XDocument Document
        {
            get { return _Document ?? (_Document = XDocument.Parse(GetLinearizedXml(Text))); }
        } private XDocument _Document;

        /// <summary>
        /// The Xml with each element properly indented on a separate line. The data is trimmed and no more than a single space anywhere.
        /// </summary>
        public string PrettyXml
        {
            get { return _PrettyXml ?? (_PrettyXml = Clean(Document, PrettySettings)); }
        } private string _PrettyXml;

        /// <summary>
        /// An enum that specifies whether to use UTF-8 or Unicode (UTF-16).
        /// Changing the encoding shouldn't change the original Text but pretty and linearized 
        /// versions of the Xml should change as well as the stream.
        /// </summary>
        public XmlEncoding Encoding { get; set; }

        /// <summary>
        /// A method that outputs the Xml as a stream. It outputs using the correct Encoding.
        /// It isn't enough to write encoding="UTF-8" in the Xml declaration if the output file
        /// is still UTF-16. Botht the labeling and the actually bits in the file should match.
        /// </summary>
        /// <returns>A file stream in the configured encoding.</returns>
        public Stream ToStream()
        {
            return new MemoryStream(ToByteArray());
        }

        /// <summary>
        /// This creates a byte array using the correct encoding.
        /// 
        /// Note: Naturally, UTF-8 has half as manay bytes as UTF-16, however,
        /// if UTF-8 is n bytes, UTF-16 will be 2*N+2 bytes. This is because
        /// "UTF-8" is five characters and "UTF-16" is six characters. 
        /// So a 100 byte UTF-8 file would be 202 bytes in UTF-16. 
        /// </summary>
        /// <returns>A byte[] array of the Xml string in the configured encoding.</returns>
        public byte[] ToByteArray()
        {
            return GetEncoding().GetBytes(PrettyXml ?? "");
        }

        /// <summary>
        /// A method to get the current encoding based on the Enum value.
        /// </summary>
        /// <returns>The correct Encoding.</returns>
        private Encoding GetEncoding()
        {
            switch (Encoding)
            {
                case XmlEncoding.UTF8:
                    return XmlUTF8Encoding.Instance;
                case XmlEncoding.UTF16:
                    return XmlUnicode.Instance;
                default:
                    return XmlUnicode.Instance;
            }
        }

        /// <summary>
        /// XmlWriterSettings for linearized Xml.
        /// </summary>
        private XmlWriterSettings LinearizedSettings
        {
            get
            {
                return new XmlWriterSettings
                    {
                        Encoding = GetEncoding(),
                        Indent = false,
                        NewLineOnAttributes = false
                    };
            }
        }

        /// <summary>
        /// XmlWriterSettings for Pretty Xml.
        /// </summary>
        private XmlWriterSettings PrettySettings
        {
            get
            {
                return new XmlWriterSettings
                {
                    Encoding = GetEncoding(),
                    Indent = true,
                    IndentChars = string.IsNullOrEmpty(IndentCharacters) ? "  " : IndentCharacters,
                    NewLineOnAttributes = false,
                    NewLineHandling = NewLineHandling.Replace
                };
            }
        }

        /// <summary>
        /// The characters to use for indenting Pretty Xml
        /// </summary>
        public string IndentCharacters { get; set; }

        /// <summary>
        /// The method that uses XDocument to do make clean (pretty or linearized) Xml
        /// </summary>
        /// <param name="doc">The XDcoument version of the Xml.</param>
        /// <param name="settings">The configured XmlWriterSettings.</param>
        /// <returns>A pretty Xml string.</returns>
        private string Clean(XDocument doc, XmlWriterSettings settings)
        {
            var sb = new StringBuilder();
            var stringWriter = new StringWriterWithEncoding(sb, GetEncoding());
            using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
            {
                doc.Save(xmlWriter);
                xmlWriter.Flush();
                return sb.ToString();
            }
        }

        /// <summary>
        /// A method that uses Regex to linearize Xml. The regex replaces methods are used.
        /// </summary>
        /// <param name="text">The Xml text</param>
        /// <returns>Linearized Xml string.</returns>
        private string GetLinearizedXml(string text)
        {
            // Replace all white space with a single space
            var halfclean = Regex.Replace(text, @"\s+", " ", RegexOptions.Singleline);

            // Trim after >.
            var clean75 = Regex.Replace(halfclean, @">\s+", ">");

            // Trim before <
            var fullclean = Regex.Replace(clean75, @"\s+<", "<");

            return fullclean;
        }

        /// <summary>
        /// This clas allows for the Xml to be created with the Xml declaration saying UTF-8
        /// </summary>
        private sealed class StringWriterWithEncoding : StringWriter
        {
            private readonly Encoding _Encoding;

            public StringWriterWithEncoding(StringBuilder builder, Encoding encoding)
                : base(builder)
            {
                _Encoding = encoding;
            }

            public override Encoding Encoding
            {
                get { return _Encoding; }
            }
        }

        /// <summary>
        /// This class makes the UTF-8 text in the Xml declaration show up capitalized.
        /// </summary>
        private sealed class XmlUTF8Encoding : UTF8Encoding
        {
            public override string WebName
            {
                get { return base.WebName.ToUpper(); }
            }

            public override string HeaderName
            {
                get { return base.HeaderName.ToUpper(); }
            }

            public override string BodyName
            {
                get { return base.BodyName.ToUpper(); }
            }

            public static XmlUTF8Encoding Instance
            {
                get { return _XmlUTF8Encoding ?? (_XmlUTF8Encoding = new XmlUTF8Encoding()); }
            } private static XmlUTF8Encoding _XmlUTF8Encoding;
        }

        /// <summary>
        /// This class makes the UTF-16 text in the Xml declaration show up capitalized.
        /// </summary>
        private sealed class XmlUnicode : UnicodeEncoding
        {
            public override string WebName
            {
                get { return base.WebName.ToUpper(); }
            }

            public override string HeaderName
            {
                get { return base.HeaderName.ToUpper(); }
            }

            public override string BodyName
            {
                get { return base.BodyName.ToUpper(); }
            }

            public static XmlUnicode Instance
            {
                get { return _XmlUnicode ?? (_XmlUnicode = new XmlUnicode()); }
            } private static XmlUnicode _XmlUnicode;
        }
    }
}

And here are some Unit Tests.

using LANDesk.Licensing.WebServices.Model;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Text;

namespace LANDesk.Licensing.WebServices.Tests.Model
{
    [TestClass]
    public class XmlTests
    {
        public string LinearUtf8Xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Person><FirstName>John</FirstName><MiddleName>Al Leon</MiddleName><LastName>Doe</LastName></Person>";
        public string PrettyUtf8Xml =
@"<?xml version=""1.0"" encoding=""UTF-8""?>
<Person>
  <FirstName>John</FirstName>
  <MiddleName>Al Leon</MiddleName>
  <LastName>Doe</LastName>
</Person>";
        public string PrettyUtf8XmlWithTabs =
@"<?xml version=""1.0"" encoding=""UTF-8""?>
<Person>
	<FirstName>John</FirstName>
	<MiddleName>Al Leon</MiddleName>
	<LastName>Doe</LastName>
</Person>";
        public string UglyUtf8Xml =
@"<?xml version=""1.0""
encoding=""UTF-8""?>
<Person>

<FirstName>
    John
        </FirstName>

<MiddleName>
    Al
    Leon
                </MiddleName>
  <LastName>
    


Doe
        </LastName>


</Person>";

        public string LinearUtf16Xml = "<?xml version=\"1.0\" encoding=\"UTF-16\"?><Person><FirstName>John</FirstName><MiddleName>Al Leon</MiddleName><LastName>Doe</LastName></Person>";
        public string PrettyUtf16Xml =
@"<?xml version=""1.0"" encoding=""UTF-16""?>
<Person>
  <FirstName>John</FirstName>
  <MiddleName>Al Leon</MiddleName>
  <LastName>Doe</LastName>
</Person>";
        public string UglyUtf16Xml =
@"<?xml version=""1.0""
encoding=""UTF-16""?>
<Person>

<FirstName>
    John
        </FirstName>

<MiddleName>
    Al
    Leon
                </MiddleName>
  <LastName>
    


Doe
        </LastName>


</Person>";

        [TestMethod]
        public void TestMethodLinearize()
        {
            // Arrange
            Xml xml = new Xml(PrettyUtf8Xml);

            // Act
            var actual = xml.LinearizeXml;

            // Assert
            Assert.AreEqual(LinearUtf8Xml, actual);
        }

        [TestMethod]
        public void TestMethodPretty()
        {
            // Arrange
            Xml xml = new Xml(LinearUtf8Xml);

            // Act
            var actual = xml.PrettyXml;

            // Assert
            Assert.AreEqual(PrettyUtf8Xml, actual);
        }

        [TestMethod]
        public void TestMethodLinearizeUgly()
        {
            // Arrange
            Xml xml = new Xml(UglyUtf8Xml);

            // Act
            var actual = xml.LinearizeXml;

            // Assert
            Assert.AreEqual(LinearUtf8Xml, actual);
        }

        [TestMethod]
        public void TestMethodMakeUglyPretty()
        {
            // Arrange
            Xml xml = new Xml(UglyUtf8Xml);

            // Act
            var actual = xml.PrettyXml;

            // Assert
            Assert.AreEqual(PrettyUtf8Xml, actual);
        }

        [TestMethod]
        public void TestMethodLinearizeUglyUtf16()
        {
            // Arrange
            Xml xml = new Xml(UglyUtf16Xml)
            {
                Encoding = Xml.XmlEncoding.UTF16
            };

            // Act
            var actual = xml.LinearizeXml;

            // Assert
            Assert.AreEqual(LinearUtf16Xml, actual);
        }

        [TestMethod]
        public void TestMethodMakeUglyPrettyUtf16()
        {
            // Arrange
            Xml xml = new Xml(UglyUtf16Xml)
            {
                Encoding = Xml.XmlEncoding.UTF16
            };

            // Act
            var actual = xml.PrettyXml;

            // Assert
            Assert.AreEqual(PrettyUtf16Xml, actual);
        }

        [TestMethod]
        public void TestMethodStreamIsUtf8()
        {
            // Arrange
            Xml xml = new Xml(UglyUtf8Xml)
            {
                Encoding = Xml.XmlEncoding.UTF8
            };

            // Act
            var actual = xml.ToStream();
            using (var memoryStream = new MemoryStream())
            {
                actual.CopyTo(memoryStream);
                var bytes = memoryStream.ToArray();
                // Assert
                Assert.AreEqual(154, bytes.Length);
            }
        }

        [TestMethod]
        public void TestMethodStreamIsUtf16()
        {
            // Arrange
            Xml xml = new Xml(UglyUtf16Xml)
            {
                Encoding = Xml.XmlEncoding.UTF16
            };

            // Act
            var actual = xml.ToStream();
            using (var memoryStream = new MemoryStream())
            {
                actual.CopyTo(memoryStream);
                var bytes = memoryStream.ToArray();

                // Assert
                // 310 is twice the size of 154, 308, but add 2 bytes because
                // UTF-8 is 5 characters but UTF-16 is 6 characters so it is 
                // one character longer.John
                Assert.AreEqual(310, bytes.Length);
            }
        }

        [TestMethod]
        public void TestMethodPrettyWuthTabs()
        {
            // Arrange
            Xml xml = new Xml(LinearUtf8Xml)
            {
                IndentCharacters = "\t"
            };

            // Act
            var actual = xml.PrettyXml;

            // Assert
            Assert.AreEqual(PrettyUtf8XmlWithTabs, actual);
        }

        [TestMethod]
        public void TestMethodStreamUtf8IsDifferentThanStreamUtf16()
        {
            const string text = "Hello, world!";

            var utf8 = Encoding.UTF8.GetBytes(text);
            var utf16 = Encoding.Unicode.GetBytes(text);

            Assert.AreNotEqual(utf8.Length, utf16.Length);
        }
    }
}

Hello Paypal Here. Goodbye Square Up.

PayPal-HereI love my new Surface Pro 3. When I go to a conference, I want my Surface Pro 3 to be used as the Cash Registers. Alas, Square Up doesn’t support the Surface Pro 3. But guess what? Paypal Here, a direct competitor to Square Up does support the Surface Pro 3. My Paypal Here card reader is on its way.

I accepted, begrudgingly, the fact that you didn’t work with my Windows 7 laptop when I first got Square Up. But that was more than two years ago. There are 300 million windows devices out there. Why would you ignore that market share?

Thank you Squareup.com for being a good card reader. I enjoyed your server. I liked it. However, you haven’t kept up with the industry. The Surface Pro 3, as well as other similar 3rd party hybrid tablet/laptops, is turning iPads and Android tablets into paperweights. You’ll be fine without me. Hopefully you update your software soon before you lose more accounts than mine. Once I am up and working with PayPal Here, I doubt I will make the effort to come back.

So I tell you goodbye Square. And hello PayPal Here!

Get PayPal Here from the Windows Store.

Note: This isn’t an ad. I wasn’t paid to make this post. I am however, frustrated with Square Up for not providing an App for my Surface Pro 3.


A cryptographically random base95 string (the ascii printable characters)

using System;
using System.Security.Cryptography;
using System.Text;

namespace LANDesk.Licensing.WebServices.Business
{
    public class CryptoRandomString
    {
        public static string GetCryptoRandomBase64String(int length)
        {
            var buffer = new byte[length];
            using (var rngCryptoServiceProvider = new RNGCryptoServiceProvider())
            {
                rngCryptoServiceProvider.GetNonZeroBytes(buffer);
            }
            return Convert.ToBase64String(buffer);
        }
        
        public static string GetCryptoRandomBaseNString(int length, byte baseN)
        {
            if (length < 1)
                throw new ArgumentException("The string length must be greater than 0!");
            if (baseN < 2)
                throw new ArgumentException("The base must be 2 or greater!");

            var buffer = new byte[length];
            var builder = new StringBuilder();

            using (var rngCryptoServiceProvider = new RNGCryptoServiceProvider())
            {
                rngCryptoServiceProvider.GetBytes(buffer);
                foreach (var b in buffer)
                {
                    var tmpbuff = new byte[] { b };
                    int max = (baseN * (256 / baseN)) - 1; // minus 1 because we start at 0
                    while (tmpbuff[0] > max)
                    {
                        rngCryptoServiceProvider.GetBytes(tmpbuff);
                    }
                    var singleChar = ByteToBaseNChar(tmpbuff[0], baseN, 32); // Start at ascii 32 (space)
                    builder.Append(singleChar);
                }
            }
            return builder.ToString();
        }

        public static string GetCryptoRandomBase95String(int length)
        {
            return GetCryptoRandomBaseNString(length, 95);
        }

        public static char ByteToBaseNChar(byte b, int baseN, int asciiOffset)
        {
            return (char)(b % baseN + asciiOffset);
        }
    }
}

And here are a few tests for it. If you can think of a additional tests, please let me know.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using LANDesk.Licensing.WebServices.Business;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace LANDesk.Licensing.WebServices.Tests.Business
{
    [TestClass]
    public class CryptoRandomStringTests
    {
        [TestMethod]
        public void TestTestThatCorrectCharacterCountIsReturned()
        {
            const int length = 100;
            var randomString = CryptoRandomString.GetCryptoRandomBase95String(length);
            Assert.AreEqual(length, randomString.Length);
        }

        [TestMethod]
        public void TestAllCharactersAreUsed()
        {
            const int length = 1000000;
            var randomString = CryptoRandomString.GetCryptoRandomBase95String(length);
            for (int i = 32; i < 126; i++)
            {
                char c = (char)i;
                Assert.IsTrue(randomString.Contains(c.ToString()));
            }
        }

        [TestMethod]
        public void TestPerformanceTenMillionCharacters()
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            const int length = 1000000;
            var randomString = CryptoRandomString.GetCryptoRandomBase95String(length);
            watch.Stop();
            Assert.IsTrue(watch.ElapsedMilliseconds < 1000);
        } // Elapsed Milliseconds 320 (it fluxuated a few milliseconds each run) 

        [TestMethod]
        public void TestPerformanceLoop()
        {
            Stopwatch watch = new Stopwatch();
            const int length = 16;
            watch.Start();
            for (int i = 0; i < 100000; i++)
            {
                var randomString = CryptoRandomString.GetCryptoRandomBase95String(length);
            }
            watch.Stop();
            Assert.IsTrue(watch.ElapsedMilliseconds < 1000);
        }

        [TestMethod]
        public void TestDistributionInTenMillionCharacters()
        {
            const int length = 1000000;
            const int distibution = length / 95;
            int[] margins = new int[9500];
            for (int j = 0; j < 100; j++)
            {
                var randomString = CryptoRandomString.GetCryptoRandomBase95String(length);
                for (int i = 32; i < 127; i++)
                {
                    //int count = randomString.Count(c => c == i);
                    int count = CountInstancesOfChar(randomString, (char)i);
                    margins[(j * 95) + i - 32] = count;
                }
            }
            Assert.IsTrue(Math.Abs(margins.Average() - distibution) < .5);
        }

        private int CountInstancesOfChar(string str, char c)
        {
            int count = 0;
            char[] strArray = str.ToCharArray();
            int length = str.Length;
            for (int n = length - 1; n >= 0; n--)
            {
                if (strArray[n] == c)
                    count++;
            }
            return count;
        }
    }
}

Basic Token Service for WCF Services (Part 2 – Database Authentication)

In the previous segment, Basic Token Service for WCF Services (Part 1), we created a project that exposes an AuthenticationTokenService and a Test1Service. The object is to first authenticate using the AuthenticationTokenService. Authentication provides a token. Calls made to additional services should include the token as a header value.

We used concrete implementations of Interfaces to do our authentication, token creation, and token validation. The concrete implementations had stubbed-in code. I used interfaces because now to change this to use database authentication, I can create concrete implementation of the same interfaces. My implementation will be different but the methods and signatures should remain the same.

Download this project here: WCF BTS DB

So here is quick table that might help you visualize what is going on. We already have the interfaces, we already have the code example code. We need to write new classes that instead of using stub example code uses database code.

Interface Concrete Code Example Class Concrete Database Class
ICredentialsValidator CodeExampleCredentialsValidator DatabaseCredentialsValidator
ITokenBuilder CodeExampleTokenBuilder DatabaseTokenBuilder
ITokenValidator CodeExampleTokenValidator DatabaseTokenValidator

OK. So we have one task to create database implementation of the interfaces. However, before we do that, we have two tasks we must do first if we are going to use a database.

  1. A database (SQL Server)
  2. A data access layer (Entity Framework)

You may already have a database, in which case, skip to Step 5& – Add Entity Framework.

Step 1 – Create the database

For now, let’s keep everything in Visual Studio. So we will create the database as a file in Visual Studio.

Note: For production deployment, we will use a real database and change the connection string in the web.config to point to the real database.

  1. Right-click on App_Data and choose Add | New Item . . . | Installed > Visual C# > Data | SQL Server Database.
  2. I named this database BasicTokenDatabase.mdf.

Step 2 – Create the User table

We will create only two tables. A user table and a Token table. A user table is needed that has at least a user and a password. The user field should be unique. The password field should NOT store the password in clear text. Instead it should store a salted hash of the password. Since we are using a salt, we need a column to store the salt. If you don’t know what a salt is, read about it here: https://crackstation.net/hashing-security.htm

  1. Double-click the database in Visual Studio.
    The Data Connections widget should open with a connection to the BasicTokenDatabase.mdf.
  2. Right-click on Tables and choose Add New Table.
  3. Keep the first Id column but also make it an identity so it autoincrements.
  4. Add three columns: User, Password, and Hash.
    The table should look as follows:

    Name Data Type Allow Nulls Default
    Id int [ ]
    User nvarchar(50) [ ]
    Password nvarchar(250) [ ]
    Salt nvarchar(250) [ ]
  5. Add a Unique constraint for the User column. I do this just by adding it to the table creation code.The SQL to create the table should look like this:
    CREATE TABLE [dbo].[User] (
        [Id]       INT            IDENTITY (1, 1) NOT NULL,
        [User]     NVARCHAR (50)  NOT NULL,
        [Password] NVARCHAR (250) NOT NULL,
        [Salt]     NVARCHAR (250) NOT NULL,
        PRIMARY KEY CLUSTERED ([Id] ASC),
        CONSTRAINT [Unique_User] UNIQUE NONCLUSTERED ([User] ASC)
    );
    
  6. Click Update to create the table.
  7. Close the table designer window.

Step 3 – Create a Token table

For the purposes of our token service, we want to create a token and store it in the database. We need a table to store the token as well as some data about the token, such as create date, and which user the token belongs to, etc.

  1. Double-click the database in Visual Studio.
    The Data Connections widget should open with a connection to the BasicTokenDatabase.mdf.
  2. Right-click on Tables and choose Add New Table.
  3. Keep the first Id column but also make it an identity so it autoincrements.
  4. Add three columns: Token, UserId, CreateDateTime.
    The table should look as follows:

    Name Data Type Allow Nulls Default
    Id int [ ]
    Token nvarchar(250) [ ]
    UserId int [ ]
    CreateDate DateTime [ ]
  5. Add a foreign key constraint for the UserId column to the Id column of the User table. I do this just by adding it to the table creation code.
  6. Add a Unique constraint for the Token column. I do this just by adding it to the table creation code. The SQL to create the table should look like this:
    CREATE TABLE [dbo].[Token] (
        [Id]         INT            IDENTITY (1, 1) NOT NULL,
        [Token]      NVARCHAR (250) NOT NULL,
        [UserId]     INT            NOT NULL,
        [CreateDate] DATETIME       NOT NULL,
        PRIMARY KEY CLUSTERED ([Id] ASC),
        CONSTRAINT [Unique_Token] UNIQUE NONCLUSTERED ([Token] ASC),
        CONSTRAINT [FK_Token_ToUser] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id])
    );
    
  7. Click Update to create the table.
  8. Close the table designer window.

Step 4 – Add a default user to the database

We need a user to test. We are going to add a user as follows:

User: user1
Password: pass1
Salt: salt1

  1. Double-click the database in Visual Studio.
    The Data Connections widget should open with a connection to the BasicTokenDatabase.mdf.
  2. Right-click on SimpleTokenConnection and choose New Query.
  3. Add SQL to insert a user.
    The sql to insert the sample user is this:

    INSERT INTO [User] ([User],[Password],[Salt]) VALUES ('user1','63dc4400772b90496c831e4dc2afa4321a4c371075a21feba23300fb56b7e19c','salt1')
    

Step 5 – Add Entity Framework

  1. Right-click on the solution and choose Manage NuGet Packages for Solution.
  2. Click Online.
  3. Type “Entity” into the search.
  4. Click Install when EntityFramework comes up.
  5. You will be prompted to accept the license agreement.

Step 6 – Add a DBContext

Entity Framework has a lot of options. Because I expect you to already have a database, I am going to use Code First to an Existing database.

  1. Create a folder called Database in your project.
  2. Right-click on the Database folder and choose Add | New Item . . . | Installed > Visual C# > Data | ADO.NET Entity Data Model.
  3. Give it a name and click OK.
    I named mine SimpleTokenDbContext.
  4. Select Code First from database.
    Your BasicTokenDatabase should selected by default. If not, you have to browse to it.
  5. I named my connection in the web.config BasicTokenDbConnection and clicked next.
  6. Expand tables and expand dbo and check the User table and the Token table.
  7. Click Finish.

You should now have three new objects created:

  1. SimpleTokenDbContext.cs
  2. Token.cs
  3. User.cs

Entity Framework will allow us to use these objects when communicating with the database.

Note: I made one change to these. Because User is a table name and a column name, Entity Framework named the class object User and the property for the user column User1. That looked wierd to me, so I renamed the User1 property to Username but I left the table with and table column named User. Token and the Token property also had this issue. I changed the Token property to be Text.

[Column("User")]
[Required]
[StringLength(50)]
public string Username { get; set; }
        [Column("Token")]
        [Required]
        [StringLength(250)]
        public string Text { get; set; }

Step 7 – Implement ICredentialsValidator

  1. Create a new class called DatabaseCredentialsValidator.cs.
  2. Use Entity Framework and the Hash class to check if those credentials match what is in the User table of the database.
using System;
using System.Linq;
using WcfSimpleTokenExample.Database;
using WcfSimpleTokenExample.Interfaces;

namespace WcfSimpleTokenExample.Business
{
    public class DatabaseCredentialsValidator : ICredentialsValidator
    {
        private readonly BasicTokenDbContext _DbContext;

        public DatabaseCredentialsValidator(BasicTokenDbContext dbContext)
        {
            _DbContext = dbContext;
        }

        public bool IsValid(Model.Credentials creds)
        {
            var user = _DbContext.Users.SingleOrDefault(u => u.Username.Equals(creds.User, StringComparison.CurrentCultureIgnoreCase));
            return user != null && Hash.Compare(creds.Password, user.Salt, user.Password, Hash.DefaultHashType, Hash.DefaultEncoding);
        }
    }
}

Step 8 – Implement ITokenBuilder

  1. Create a new class called DatabaseTokenBuilder.cs.
  2. Use Entity Framework to create a new token and add it to the Token table in the database.
  3. Instead of using Guid.NewGuid, which isn’t secure because it may not be cryptographically random, we will create a better random string generator using RNGCryptoServiceProvider. Se the BuildSecureToken() method below.
using System;
using System.Linq;
using System.Security.Authentication;
using System.Security.Cryptography;
using WcfSimpleTokenExample.Database;
using WcfSimpleTokenExample.Interfaces;

namespace WcfSimpleTokenExample.Business
{
    public class DatabaseTokenBuilder : ITokenBuilder
    {
        public static int TokenSize = 100;
        private readonly BasicTokenDbContext _DbContext;

        public DatabaseTokenBuilder(BasicTokenDbContext dbContext)
        {
            _DbContext = dbContext;
        }

        public string Build(Model.Credentials creds)
        {
            if (!new DatabaseCredentialsValidator(_DbContext).IsValid(creds))
            {
                throw new AuthenticationException();
            }
            var token = BuildSecureToken(TokenSize);
            var user = _DbContext.Users.SingleOrDefault(u => u.Username.Equals(creds.User, StringComparison.CurrentCultureIgnoreCase));
            _DbContext.Tokens.Add(new Token { Text = token, User = user, CreateDate = DateTime.Now });
            _DbContext.SaveChanges();
            return token;
        }

        private string BuildSecureToken(int length)
        {
            var buffer = new byte[length];
            using (var rngCryptoServiceProvider = new RNGCryptoServiceProvider())
            {
                rngCryptoServiceProvider.GetNonZeroBytes(buffer);
            }
            return Convert.ToBase64String(buffer);
        }
    }
}

Step 9 – Implement ITokenValidator

  1. Create a new class called DatabaseTokenValidator.cs.
  2. Read the token from the header data.
  3. Use Entity Framework to verify the token is valid.
using System;
using System.Linq;
using WcfSimpleTokenExample.Database;
using WcfSimpleTokenExample.Interfaces;

namespace WcfSimpleTokenExample.Business
{
    public class DatabaseTokenValidator : ITokenValidator
    {
        // Todo: Set this from a web.config appSettting value
        public static double DefaultSecondsUntilTokenExpires = 1800;

        private readonly BasicTokenDbContext _DbContext;

        public DatabaseTokenValidator(BasicTokenDbContext dbContext)
        {
            _DbContext = dbContext;
        }

        public bool IsValid(string tokentext)
        {
            var token = _DbContext.Tokens.SingleOrDefault(t => t.Text == tokentext);
            return token != null && !IsExpired(token);
        }

        internal bool IsExpired(Token token)
        {
            var span = DateTime.Now - token.CreateDate;
            return span.TotalSeconds > DefaultSecondsUntilTokenExpires;
        }
    }
}

Step 10 – Update the services code

Ideally we would have our services code automatically get the correct interface implementations. But for this example, we want to keep things as simple as possible.

using System.Security.Authentication;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using WcfSimpleTokenExample.Business;
using WcfSimpleTokenExample.Database;
using WcfSimpleTokenExample.Interfaces;
using WcfSimpleTokenExample.Model;

namespace WcfSimpleTokenExample.Services
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class AuthenticationTokenService
    {
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        [OperationContract]
        public string Authenticate(Credentials creds)
        {
            using (var dbContext = new BasicTokenDbContext())
            {
                ICredentialsValidator validator = new DatabaseCredentialsValidator(dbContext);
                if (validator.IsValid(creds))
                    return new DatabaseTokenBuilder(dbContext).Build(creds);
                throw new InvalidCredentialException("Invalid credentials");
            }
        }
    }
}
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Web;
using WcfSimpleTokenExample.Business;
using WcfSimpleTokenExample.Database;
using WcfSimpleTokenExample.Interfaces;

namespace WcfSimpleTokenExample.Services
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Test1Service
    {
        [OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        public string Test()
        {
            var token = HttpContext.Current.Request.Headers["Token"]; // This works whether aspNetCompatibilityEnabled is true of false.
            using (var dbContext = new BasicTokenDbContext())
            {
                ITokenValidator validator = new DatabaseTokenValidator(dbContext);
                return validator.IsValid(token) ? "Your token worked!" : "Your token failed!";
            }
        }
    }
}

I didn’t make any changes to the web.config myself. However, the web.config was changed by adding Entity Framework and a database. Download the source code to see and example of it.

Testing using Postman

The steps for testing with Postman in Part 1 should still be valid for Part 2. Just remember to remove any escape characters from the returned string. For example, if a \/ is found, remove the \ as it is an escape character. If you look at the resulting token in Postman’s Pretty tab, the escape character is removed for you.

Well, by now, you should be really getting this down. Hopefully but this point, you can now take this code and implement your own Basic Token Service BTS. Hopefully you can use this where simple token authentication is needed and the bloat of an entire Secure Token Service framework is not.

Go on and read part 3 here: Basic Token Service for WCF Services (Part 3 – Token Validation in IDispatchMessageInspector)


Basic Token Service for WCF Services (Part 1)

I am setting out to create a thin web UI that consists of only HTML, CSS, and Javascript (HCJ) for the front end. For the back end, I have Ajax-enabled WCF services.

I have a couple of options for authentication.

Options:

  1. Authenticate with username and password every time a service is called.
  2. Store the username and password once, then store the credentials in the session or a cookie or a javascript variable and pass them every time I call a subsequent service.
  3. Authentication to one WCF service, then store a token.

Option 1 – Authenticate every time

This is not acceptable to the users. It would be a pain to type in credentials over and over again when clicking around a website.

Option 2 – Authenticate once and store credentials

This option is not acceptable because we really don’t want to be storing credentials in cookies and headers. You could alleviate the concern by hashing the password and only storing the hash, but that is still questionable. It seems this might cause the username and password to be passed around too often and eventually, your credentials will be leaked.

Option 3 – Authenticate once and store a token

This option seems the most secure. After authenticating, a token is returned to the user. The other web services can be accessed by using the token. Now the credentials are not stored. They are only passed over the network at authentication time.

Secure Token Service

This third idea is the idea around the Secure Token Service (STS). However, the STS is designed around the idea of having a 3rd party provide authentication, for example, when you login to a website using Facebook even though it isn’t a Facebook website.

STS service implementation is complex. There are entire projects built around this idea. What if you want something simpler?

Basic Token Service (BTS)

I decided that for simple authentication, there needs to be an example on the web of a Basic Token Service.

In the basic token service, there is a the idea of a single service that provides authentication. That service returns a token if authenticated, a failure otherwise. If authenticated, the front end is responsible for passing the token to any subsequent web services. This could be a header value, a cookie or a url parameter. I am going to use a header value in my project.

Here is the design.

Basic Token Service

Since this is “Basic” it should use basic code, right? It does.

The BTS Code

Download here: WCF BTS

In Visual Studio, I chose New | Project | Installed > Templates > Visual C# > WCF | WCF Service Application.

OK, so lets do some simple code. In this example, we will put everything in code. (In part 2, I will enhance the code to look to the database.)

Ajax-enabled WCF Services

Add the Authentication WCF Service first. In Visual Studio, I right-clicked on the project and chose Add | New Item … | Installed > Visual C# > Web | WCF Service (Ajax-enabled)

<%@ ServiceHost Language="C#" Debug="true" Service="WcfSimpleTokenExample.Services.AuthenticationTokenService" CodeBehind="AuthenticationTokenService.svc.cs" %>
using System.Security.Authentication;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using WcfSimpleTokenExample.Business;
using WcfSimpleTokenExample.Interfaces;
using WcfSimpleTokenExample.Model;

namespace WcfSimpleTokenExample.Services
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class AuthenticationTokenService
    {
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        [OperationContract]
        public string Authenticate(Credentials creds)
        {
            ICredentialsValidator validator = new CodeExampleCredentialsValidator();
            if (validator.IsValid(creds))
                return new CodeExampleTokenBuilder().Build(creds);
            throw new InvalidCredentialException("Invalid credentials");
        }
    }
}

A second example service:

<%@ ServiceHost Language="C#" Debug="true" Service="WcfSimpleTokenExample.Services.Test1Service" CodeBehind="Test1Service.svc.cs" %>
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Web;
using WcfSimpleTokenExample.Business;
using WcfSimpleTokenExample.Interfaces;

namespace WcfSimpleTokenExample.Services
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Test1Service
    {
        [OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        public string Test()
        {
            var token = HttpContext.Current.Request.Headers["Token"];
            ITokenValidator validator = new CodeExampleTokenValidator();
            if (validator.IsValid(token))
            {
                return "Your token worked!";
            }
            else
            {
                return "Your token failed!";
            }
        }
    }
}
<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfSimpleTokenExample.Services.AuthenticationTokenService" behaviorConfiguration="ServiceBehaviorHttp" >
        <endpoint address="" behaviorConfiguration="AjaxEnabledBehavior" binding="webHttpBinding" contract="WcfSimpleTokenExample.Services.AuthenticationTokenService" />
      </service>
      <service name="WcfSimpleTokenExample.Services.Test1Service" behaviorConfiguration="ServiceBehaviorHttp" >
        <endpoint address="" behaviorConfiguration="AjaxEnabledBehavior" binding="webHttpBinding" contract="WcfSimpleTokenExample.Services.Test1Service" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="AjaxEnabledBehavior">
          <webHttp helpEnabled="true" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviorHttp">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

Note: In the project, there is an xdt:Transform for the web.config.debug and the web.config.release if you use web deploy. These enforce that the web services that make them only use HTTPS. Check them out.

Models

Now we are going to have a single class in the Model for this basic example, a Credentials class.

namespace WcfSimpleTokenExample.Model
{
    public class Credentials
    {
        public string User { get; set; }
        public string Password { get; set; }
    }
}

Interfaces

using WcfSimpleTokenExample.Model;

namespace WcfSimpleTokenExample.Interfaces
{
    public interface ICredentialsValidator
    {
        bool IsValid(Credentials creds);
    }
}
using WcfSimpleTokenExample.Model;

namespace WcfSimpleTokenExample.Interfaces
{
    interface ITokenBuilder
    {
        string Build(Credentials creds);
    }
}
namespace WcfSimpleTokenExample.Interfaces
{
    public interface ITokenValidator
    {
        bool IsValid(string token);
    }
}

Business Implementations

using WcfSimpleTokenExample.Interfaces;
using WcfSimpleTokenExample.Model;

namespace WcfSimpleTokenExample.Business
{
    public class CodeExampleCredentialsValidator : ICredentialsValidator
    {
        public bool IsValid(Credentials creds)
        {
            // Check for valid creds here
            // I compare using hashes only for example purposes
            if (creds.User == "user1" && Hash.Get(creds.Password, Hash.HashType.SHA256) == Hash.Get("pass1", Hash.HashType.SHA256))
                return true;
            return false;
        }
    }
}
using System.Security.Authentication;
using WcfSimpleTokenExample.Interfaces;
using WcfSimpleTokenExample.Model;

namespace WcfSimpleTokenExample.Business
{
    public class CodeExampleTokenBuilder : ITokenBuilder
    {
        internal static string StaticToken = "{B709CE08-D2DE-4201-962B-3BBAC74C5952}";

        public string Build(Credentials creds)
        {
            if (new CodeExampleCredentialsValidator().IsValid(creds))
                return StaticToken;
            throw new AuthenticationException();
        }
    }
}
using WcfSimpleTokenExample.Interfaces;

namespace WcfSimpleTokenExample.Business
{
    public class CodeExampleTokenValidator : ITokenValidator
    {
        public bool IsValid(string token)
        {
            return CodeExampleTokenBuilder.StaticToken == token;
        }
    }
}

I also use the Hash.cs file from this post: A C# class to easily create an md5, sha1, sha256, or sha512 hash.

Demo

I use the Postman plugin for Chrome. Postman

Step 1 – Authenticate and acquire token

PostmanAuthReceive

Step 2 – Call subsequent service

PostmanTestReceive

Part 1 uses examples that are in subbed in statically in the code. In Basic Token Service for WCF Services (Part 2 – Database Authentication), we will enhance this to use a database for credentials validation and token storage and token validation.


A C# class to easily create an md5, sha1, sha256, or sha512 hash

I started making a class to make hashing easier in C#. I found someone who had done this already here: http://techlicity.com/blog/dotnet-hash-algorithms

That was a good start. I just needed to:

  1. Add unit tests
  2. Remove the duplicate code (condense the class)
  3. Add a default values, such as a default Encoding and to use sha256 by default.
  4. Add easier salt handling.

I condensed the code (by more than half the lines by the way) and now have this much easier to read and test class:

using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace WcfSimpleTokenExample.Business
{
    public class Hash
    {
        public static Encoding DefaultEncoding = Encoding.UTF8;
        public const HashType DefaultHashType = HashType.SHA256;

        public enum HashType
        {
            MD5,
            SHA1,
            SHA256,
            SHA512
        }

        public static string Get(string text, HashType hashType = DefaultHashType, Encoding encoding = null)
        {
            switch (hashType)
            {
                case HashType.MD5:
                    return Get(text, new MD5CryptoServiceProvider(), encoding);
                case HashType.SHA1:
                    return Get(text, new SHA1Managed(), encoding);
                case HashType.SHA256:
                    return Get(text, new SHA256Managed(), encoding);
                case HashType.SHA512:
                    return Get(text, new SHA512Managed(), encoding);
                default:
                    throw new CryptographicException("Invalid hash alrgorithm.");
            }
        }

        public static string Get(string text, string salt, HashType hashType = DefaultHashType, Encoding encoding = null)
        {
            return Get(text + salt, hashType, encoding);
        }

        public static string Get(string text, HashAlgorithm algorithm, Encoding encoding = null)
        {
            byte[] message = (encoding == null) ? DefaultEncoding.GetBytes(text) : encoding.GetBytes(text);
            byte[] hashValue = algorithm.ComputeHash(message);
            return hashValue.Aggregate(string.Empty, (current, x) => current + string.Format("{0:x2}", x));
        }

        public static bool Compare(string original, string hashString, HashType hashType = DefaultHashType, Encoding encoding = null)
        {
            string originalHash = Get(original, hashType, encoding);
            return (originalHash == hashString);
        }

        public static bool Compare(string original, string salt, string hashString, HashType hashType = DefaultHashType, Encoding encoding = null)
        {
            return Compare(original + salt, hashString, hashType, encoding);
        }
    }
}

Here are some unit tests using MSTest.

using System;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WcfSimpleTokenExample.Business;

namespace WcfSimpleTokenExample.Tests
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void MD5Test()
        {
            // Arrange
            const string tobehashed = "1";
            // Got comparison hash from here: http://www.xorbin.com/tools/md5-hash-calculator
            // Also verified with md5sums.exe
            const string expectedHash = "c4ca4238a0b923820dcc509a6f75849b";

            // Act
            string actualHash = Hash.Get(tobehashed, Hash.HashType.MD5);

            // Assert
            Assert.AreEqual(expectedHash, actualHash);
        }

        [TestMethod]
        public void Sha1Test()
        {
            // Arrange
            const string tobehashed = "1";
            // Got comparison hash from here: http://www.xorbin.com/tools/sha1-hash-calculator
            // Also verified with sha1sums.exe
            const string expectedHash = "356a192b7913b04c54574d18c28d46e6395428ab";

            // Act
            string actualHash = Hash.Get(tobehashed, Hash.HashType.SHA1);

            // Assert
            Assert.AreEqual(expectedHash, actualHash);
        }

        [TestMethod]
        public void Sha256Test()
        {
            // Arrange
            const string tobehashed = "1";
            // Got comparison hash from here: http://www.xorbin.com/tools/sha256-hash-calculator
            // Also verified with sha1sums.exe
            const string expectedHash = "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b";

            // Act
            string actualHash = Hash.Get(tobehashed, Hash.HashType.SHA256);

            // Assert
            Assert.AreEqual(expectedHash, actualHash);
        }

        [TestMethod]
        public void Sha512Test()
        {
            // Arrange
            const string tobehashed = "1";
            // Got comparison hash from here:  http://www.miniwebtool.com/sha512-hash-generator/
            const string expectedHash = "4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a";

            // Act
            string actualHash = Hash.Get(tobehashed, Hash.HashType.SHA512);

            // Assert
            Assert.AreEqual(expectedHash, actualHash);
        }
    }
}