Browse Tag: security

WCF custom authentication using ServiceCredentials

The generally accepted way of authenticating a user with WCF is with a User Name and Password with the UserNamePasswordValidator class.  So common that even MSDN has a tutorial, and the MSDN documentation for WCF is seriously lacking at best.  The username/password approach does what it says on the tin, you pass along a username and password credential from the client to the server, do your authentication, and only if there is a problem then you throw an exception.  It’s a primitive approach, but it works.  But what about when you want to do something a little bit less trivial than that? ServiceCredentials is probably what you need.

Source code for this post is available on GitHub.


I should prefix this tutorial with a disclaimer, and this disclaimer is just my opinion.  WCF is incredibly poorly documented and at times counter intuitive.  In fact, I generally avoid WCF development like the black plague, preferring technologies such as Web API.  The saving grace of WCF is that you have full control over a much more substantial set of functionality, and you’re not limited by REST but empowered by SOAP.  WCF plays particularly nicely with WPF, my favourite desktop software technology.  I’ve never used WCF as part of a web service before, and I doubt I ever will.

Tangent aside, sometimes its not appropriate to authenticate a user with simply a username or password.  You might want to pass along a User Name and a License Key, along with some kind of unique identification code based on the hardware configuration of the users computer.  Passing along this kind of information in a clean way can’t be done with the simple UserNamePasswordValidator, without using some hacky kind of delimited string approach (“UserName~LicenseKey~UniqueCode”).

So this is what we will do for this tutorial; pass a User Name, License Key and “Unique Key” from the client to the server for authentication and authorization.  And for security, we will avoid using WsHttpBinding and instead create a CustomBinding and use an SSL certificate (PFX on the server, CER on the client).  The reasons for this are discussed throughout this tutorial, but primarily because I’ve encountered so many problems with WsHttpBinding when used in a load balanced environment that its just not worth the hassle.

As a final note, we will also go “configuration free”.   All of this is hard coded because I can’t make the assumption that if you use this code in a production environment that you will have access to the machine certificate store, which a lot of web hosting providers restrict access to. As far as I know, the SSL certificate cannot be loaded from a file or a resource using the Web.config.

Server Side Implementation

Basic Structure

All preamble aside, lets dive straight in.  This tutorial isn’t about creating a full featured WCF service (a quick Google of the term “WCF Tutorial” presents about 878,000 results for that) so the specific implementation details aren’t important.  What is important is that you have a Service Contract with at least one Operation Contract, for testing purposes.  Create a new WCF Service Application in Visual Studio, and refactor the boiler plate code as follows;

public interface IEchoService
    string Echo(int value);

public class EchoService : IEchoService
    public string Echo(int value)
        return string.Format("You entered: {0}", value);

And rename the SVC file to EchoService.svc.

Open up the Web.config file and delete everything inside the <system.serviceModel> element.  You don’t need any of that.

NuGet Package

It is not exactly clear to me why, but you’ll also need to install the NuGet package Microsoft ASP.NET Web Pages (Install-Package Microsoft.AspNet.WebPages).  I suppose this might be used for the WSDL definition page or the help page.  I didn’t really look into it.


Hosting In Local IIS (Internet Information Services)

I’m hosting this in IIS on my local machine (using a self-signed certificate) but I’ve thoroughly tested on a real server using a “real” SSL certificate, so I’ll give you some helpful hints of that as we go along.

First things first;

  1. Open IIS Manager (inetmgr)
  2. Add a new website called “echo”
  3. Add a HTTP binding with the host name “echo.local”
  4. Open up the hosts file (C:\Windows\System32\drivers\etc) and add an entry for “echo.local” and IP address
  5. Use your favourite SSL self signed certificate creation tool to generate a certificate for cn=echo.local  (See another tutorial I wrote that explains how to do this).  Be sure to save the SSL certificate in PFX format, this is important for later.
  6. The quickest way I’ve found to generate the CER file (which is the certificate excluding the private key, for security) is to import the PFX into the Personal certificate store for your local machine.  Then right click > All Tasks > Export (excluding private key) and select DER encoded binary X.509 (.CER).  Save to some useful location for use later.  Naturally when doing this “for real”, your SSL certificate provider will provide the PFX and CER (and tonnes of other formats) so you can skip this step.  This tutorial assumes you don’t have access to the certificate store (either physically or programmatically) on the production machine.
  7. DO NOT add a binding for HTTPS unless you are confident that your web host fully supports HTTPS connections.  More on this later.
  8. Flip back to Visual Studio and publish your site to IIS.  I like to publish in “Debug” mode initially, just to make debugging slightly less impossible.


Open your favourite web browser and navigate to http://echo.local/EchoService.svc?wsdl.  You won’t get much of anything at this time, just a message to say that service metadata is unavailable and instructions on how to turn it on.  Forget it, its not important.

Beyond UserNamePasswordValidator

Normally at this stage you would create a UserNamePasswordValidator, add your database/authentication/authorization logic and be done after about 10 minutes of effort.  Well forget that, you should expect to spend at least the next hour creating a myriad of classes and helpers, authenticators, policies, tokens, factories and credentials.  Hey, I never said this was easy, just that it can be done.

Factory Pattern

The default WCF Service Application template you used to create the project generates a ServiceHost object with a Service property that points to the actual implementation of our service, the guts.  We need to change this to use a ServiceHostFactory, which will spawn new service hosts for us.  Right click on the EchoService.svc file and change the Service property to Factory, and EchoService to EchoServiceFactory;



Just before we continue, add a new class to your project called EchoServiceHost and derive from ServiceHost.  This is the actual ServiceHost that was previously created automatically under the hood for us.  We will flesh this out over the course of the tutorial.  For now, just add a constructor that takes an array of base addresses for our service, and which passes the type of the service to the base.

public class EchoServiceHost : ServiceHost
    public EchoServiceHost(params Uri[] addresses)
        : base(typeof(EchoService), addresses)


Now add another new class to your project, named EchoServiceFactory, and derived from ServiceHostFactoryBase.  Override CreateServiceHost and return a new instance of EchoServiceHost with the appropriate base address.

public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    return new EchoServiceHost(new[]
        new Uri("http://echo.local/")

We won’t initialize the ServiceHost just let, we’ll come back to that later.

Custom ServiceCredentials

ServiceCredentials has many responsibilities, including; serialization/deserialization and authentication/authorization.  Not to be confused with ClientCredentials, which has the additional responsibility of generating a token which contains all the fields to pass to the service (User Name, License Key and Unique Code).  There is a pretty decent tutorial on MSDN which explains some concepts in a little bit more detail that I will attempt.  The ServiceCredentials will (as well as all the aforementioned things) load in our SSL certificate and use that to verify (using the private key) that the certificate passed from the client is valid before attempting authentication/authorization. Before creating the ServiceCredentials class, add each of the following;

  1. EchoServiceCredentialsSecurityTokenManager which derives from ServiceCredentialsSecurityTokenManager.
  2. EchoSecurityTokenAuthenticator which derives from SecurityTokenAuthenticator.

Use ReSharper or Visual Studio IntelliSense to stub out any abstract methods for the time being.  We will flesh these out as we go along.

You will need to add a reference to System.IdentityModel, which we will need when creating our authorization policies next.

You can now flesh out the EchoServiceCredentials class as follows;

public class EchoServiceCredentials : ServiceCredentials
    public override SecurityTokenManager CreateSecurityTokenManager()
        return new EchoServiceCredentialsSecurityTokenManager(this);

    protected override ServiceCredentials CloneCore()
        return new EchoServiceCredentials();

If things are not clear at this stage, stick with me… your understanding will improve as we go along.

Namespaces and constant values

Several namespaces are required to identify our custom token and its properties.  It makes sense to stick these properties all in one place as constants, which we will also make available to the client later.  The token is ultimately encrypted using a Symmetric encryption algorithm (as shown later), so we can’t see the namespaces in the resulting SOAP message, but I’m sure they’re there.

Create a new class called EchoConstants, and add the following;

public class EchoConstants
    public const string EchoNamespace = "https://echo/";

    public const string EchoLicenseKeyClaim = EchoNamespace + "Claims/LicenseKey";
    public const string EchoUniqueCodeClaim = EchoNamespace + "Claims/UniqueCode";
    public const string EchoUserNameClaim = EchoNamespace + "Claims/UserName";
    public const string EchoTokenType = EchoNamespace + "Tokens/EchoToken";

    public const string EchoTokenPrefix = "ct";
    public const string EchoUrlPrefix = "url";
    public const string EchoTokenName = "EchoToken";
    public const string Id = "Id";
    public const string WsUtilityPrefix = "wsu";
    public const string WsUtilityNamespace = "";

    public const string EchoLicenseKeyElementName = "LicenseKey";
    public const string EchoUniqueCodeElementName = "UniqueCodeKey";
    public const string EchoUserNameElementName = "UserNameKey";

All these string values (except for the WsUtilityNamespace) are arbitrary values.  They give the message structure and conformity with open standards.

We will use these constant values throughout the remainder of the tutorial.

Security Token

Lets work through this starting with the most interesting classes first, and work backwards in descending order.  The SecurityToken contains all our custom credentials that we will ultimately use to determine if the user is allowed to use the service.  A security token can contain pretty much anything you want, as long as the token itself has a unique ID, and a valid from/to date and time.

Add the following class to your project;

public class EchoToken : SecurityToken
    private readonly DateTime _effectiveTime = DateTime.UtcNow;
    private readonly string _id;
    private readonly ReadOnlyCollection<SecurityKey> _securityKeys;

    public string LicenseKey { get; set; }
    public string UniqueCode { get; set; }
    public string UserName { get; set; }

    public EchoToken(string licenseKey, string uniqueCode, string userName, string id = null)
        LicenseKey = licenseKey;
        UniqueCode = uniqueCode;
        UserName = userName;

        _id = id ?? Guid.NewGuid().ToString();
        _securityKeys = new ReadOnlyCollection<SecurityKey>(new List<SecurityKey>());

    public override string Id
        get { return _id; }

    public override ReadOnlyCollection<SecurityKey> SecurityKeys
        get { return _securityKeys; }

    public override DateTime ValidFrom
        get { return _effectiveTime; }

    public override DateTime ValidTo
        get { return DateTime.MaxValue; }

There are a few things to note here;

  1. The token has a unique identifier, in this case a random Guid.  You can use whatever mechanism you like here, as long as it results in a unique identifier for the token.
  2. The token is valid from now until forever.  You might want to put a realistic timeframe in place here.
  3. I don’t know what SecurityKeys is for, and it doesn’t seem to matter.

Before you rush off to MSDN, here is what it says;

Base class for security keys.


We’re not quite ready to use this token yet, so we’ll revisit later.  All the pieces come together at once, like a really dull jigsaw.

Authorization Policy

We only care at this point about authorizing the request based on the User Name, License Key and Unique Code provided in the token.  We could however use an Authorization Policy to limit access to certain service methods based on any one of these factors.  If you want to restrict access to your API in this way, see the MSDN documentation for more information.  If, however, the basic authorization is good enough for you, add the following code;

public class EchoTokenAuthorizationPolicy : IAuthorizationPolicy
    private readonly string _id;
    private readonly IEnumerable<ClaimSet> _issuedClaimSets;
    private readonly ClaimSet _issuer;

    public EchoTokenAuthorizationPolicy(ClaimSet issuedClaims)
        if (issuedClaims == null)
            throw new ArgumentNullException("issuedClaims");

        _issuer = issuedClaims.Issuer;
        _issuedClaimSets = new[] { issuedClaims };
        _id = Guid.NewGuid().ToString();

    public ClaimSet Issuer
        get { return _issuer; }

    public string Id
        get { return _id; }

    public bool Evaluate(EvaluationContext context, ref object state)
        foreach (ClaimSet issuance in _issuedClaimSets)
            context.AddClaimSet(this, issuance);

        return true;

The key to this working is the Evaluate method.  We are just adding each claim to the EvaluationContext claim set, without doing any sort of checks.  This is fine because we will do our own authorization as part of the SecurityTokenAuthenticator, shown next.

Security Token Authentication and Authorization

Now that we have our Authorization Policies in place, we can get down to business and tell WCF to allow or deny the request.  We must create a class that derives from SecurityTokenAuthenticator, and override the ValidateTokenCore method.  If an exception is thrown in this method, the request will be rejected.  You’re also required to return the authorization policies, which will be evaluated accordingly and the request rejected if the token does not have the claims required to access the desired operation.  How you authorize/authenticate the request is down to you, but will inevitably involve some database call or similar tasks to check for the existence and legitimacy of the given token parameters.

Here is a sample implementation;

public class EchoSecurityTokenAuthenticator : SecurityTokenAuthenticator
    protected override bool CanValidateTokenCore(SecurityToken token)
        return (token is EchoToken);

    protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
        var echoToken = token as EchoToken;

        if (echoToken == null)
            throw new ArgumentNullException("token");

        var authorizationException = IsAuthorized(echoToken.LicenseKey, echoToken.UniqueCode, echoToken.UserName);
        if (authorizationException != null)
            throw authorizationException;

        var policies = new List<IAuthorizationPolicy>(3)
            CreateAuthorizationPolicy(EchoConstants.EchoLicenseKeyClaim, echoToken.LicenseKey, Rights.PossessProperty),
            CreateAuthorizationPolicy(EchoConstants.EchoUniqueCodeClaim, echoToken.UniqueCode, Rights.PossessProperty),
            CreateAuthorizationPolicy(EchoConstants.EchoUserNameClaim, echoToken.UserName, Rights.PossessProperty),

        return policies.AsReadOnly();

    private static Exception IsAuthorized(string licenseKey, string uniqueCode, string userName)
        Exception result = null;

        //Check if user is authorized.  If not you must return a FaultException

        return result;

    private static EchoTokenAuthorizationPolicy CreateAuthorizationPolicy<T>(string claimType, T resource, string rights)
        return new EchoTokenAuthorizationPolicy(new DefaultClaimSet(new Claim(claimType, resource, rights)));

Token Serialization

Before we can continue, we have neglected to discuss one very important detail.  WCF generates messages in XML SOAP format for standardised communication between the client and the server applications.  This is achieved by serializing the token using a token serializer.  Surprisingly, however, this doesn’t happen automatically.  You have to give WCF a hand and tell it exactly how to both read and write the messages.  It gives you the tools (an XmlReader and XmlWriter) but you have to do the hammering yourself.

The code for this isn’t short, so I apologise for that.  Here is an explanation of what happens;

  1. CanReadTokenCore is called when deserializing a token.  The responsibility of this method is to tell the underlying framework if this class is capable of reading the token contents.
  2. ReadTokenCore is called with an XmlReader, which provides access to the raw token itself.  You use the XmlReader to retrieve the parts of the token of interest (the User Name, Unique Code and License Key) and ultimately return a new SecurityToken (EchoSecurityToken).
  3. CanWriteTokenCore is called when serializing a token.  Return true if the serializer is capable of serializing then given token.
  4. WriteTokenCore is called with an XmlWriter and the actual SecurityToken.  Use both objects to do the serialization manually.

And the code itself;

public class EchoSecurityTokenSerializer : WSSecurityTokenSerializer
    private readonly SecurityTokenVersion _version;

    public EchoSecurityTokenSerializer(SecurityTokenVersion version)
        _version = version;

    protected override bool CanReadTokenCore(XmlReader reader)
        if (reader == null)
            throw new ArgumentNullException("reader");
        if (reader.IsStartElement(EchoConstants.EchoTokenName, EchoConstants.EchoNamespace))
            return true;
        return base.CanReadTokenCore(reader);

    protected override SecurityToken ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)
        if (reader == null)
            throw new ArgumentNullException("reader");
        if (reader.IsStartElement(EchoConstants.EchoTokenName, EchoConstants.EchoNamespace))
            string id = reader.GetAttribute(EchoConstants.Id, EchoConstants.WsUtilityNamespace);


            string licenseKey = reader.ReadElementString(EchoConstants.EchoLicenseKeyElementName, EchoConstants.EchoNamespace);
            string companyKey = reader.ReadElementString(EchoConstants.EchoUniqueCodeElementName, EchoConstants.EchoNamespace);
            string machineKey = reader.ReadElementString(EchoConstants.EchoUniqueCodeElementName, EchoConstants.EchoNamespace);


            return new EchoToken(licenseKey, companyKey, machineKey, id);
        return DefaultInstance.ReadToken(reader, tokenResolver);

    protected override bool CanWriteTokenCore(SecurityToken token)
        if (token is EchoToken)
            return true;
        return base.CanWriteTokenCore(token);

    protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)
        if (writer == null)
            throw new ArgumentNullException("writer");
        if (token == null)
            throw new ArgumentNullException("token");

        var EchoToken = token as EchoToken;
        if (EchoToken != null)
            writer.WriteStartElement(EchoConstants.EchoTokenPrefix, EchoConstants.EchoTokenName, EchoConstants.EchoNamespace);
            writer.WriteAttributeString(EchoConstants.WsUtilityPrefix, EchoConstants.Id, EchoConstants.WsUtilityNamespace, token.Id);
            writer.WriteElementString(EchoConstants.EchoLicenseKeyElementName, EchoConstants.EchoNamespace, EchoToken.LicenseKey);
            writer.WriteElementString(EchoConstants.EchoUniqueCodeElementName, EchoConstants.EchoNamespace, EchoToken.UniqueCode);
            writer.WriteElementString(EchoConstants.EchoUserNameElementName, EchoConstants.EchoNamespace, EchoToken.UserName);
            base.WriteTokenCore(writer, token);

Service Credentials Security Token Manager

A long time ago… in a blog post right here, you created a class called EchoServiceCredentialsSecurityTokenManager.  The purpose of this class is to tell WCF that we want to use our custom token authenticator (EchoSecurityTokenAuthenticator) when it encounters our custom token.

Update the EchoServiceCredentialsSecurityTokenManager as follows;

public class EchoServiceCredentialsSecurityTokenManager : ServiceCredentialsSecurityTokenManager
    public EchoServiceCredentialsSecurityTokenManager(ServiceCredentials parent)
        : base(parent)

    public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
        if (tokenRequirement.TokenType == EchoConstants.EchoTokenType)
            outOfBandTokenResolver = null;
            return new EchoSecurityTokenAuthenticator();
        return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);

    public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
        return new EchoSecurityTokenSerializer(version);

The code is pretty self explanatory.  When an EchoToken is encountered, use the EchoSecurityTokenAuthenticator to confirm that the token is valid, authentic and authorized.  Also, the token can be serialized/deserialized using the EchoSecurityTokenSerializer.

Service Host Endpoints

The last remaining consideration is exposing endpoints so that the client has “something to connect to”.  This is done in EchoServiceHost by overriding the InitializeRuntime method, as shown;

protected override void InitializeRuntime()
    var baseUri = new Uri("http://echo.local");
    var serviceUri = new Uri(baseUri, "EchoService.svc");


    var serviceCredential = new EchoServiceCredentials();
    serviceCredential.ServiceCertificate.Certificate = new X509Certificate2(Resources.echo, string.Empty, X509KeyStorageFlags.MachineKeySet);

    var behaviour = new ServiceMetadataBehavior { HttpGetEnabled = true, HttpsGetEnabled = false };

    Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
    Description.Behaviors.Find<ServiceDebugBehavior>().HttpHelpPageUrl = serviceUri;

    AddServiceEndpoint(typeof(IEchoService), new BindingHelper().CreateHttpBinding(), string.Empty);


The code does the following;

  1. Define the base URL of the and the service URL
  2. Remove the default implementation of ServiceCredentials, and replace with our custom implementation.  Ensure that the custom implementation uses our SSL certificate (in this case, the SSL certificate is added to the project as a resource).  If the PFX (and it must be a PFX) requires a password, be sure to specify it.
  3. Define and add a metadata endpoint (not strictly required)
  4. Turn on detailed exceptions for debugging purposes, and expose a help page (again not strictly required)
  5. Add an endpoint for our service, use a custom binding.  (DO NOT attempt to use WsHttpBinding or BasicHttpsBinding, you will lose 4 days of your life trying to figure out why it doesn’t work in a load balanced environment!)

Custom Http Binding

In the interest of simplicity, I want the server and the client to use the exact same binding.  To make this easier, I’ve extracted the code out into a separate helper class which will be referenced by both once we’ve refactored (discussed next).  We’re using HTTP  right now but we will discuss security and production environments towards the end of the post.  The custom binding will provide some level of security via a Symmetric encryption algorithm that will be applied to aspects of the message.

public Binding CreateHttpBinding()
    var httpTransport = new HttpTransportBindingElement
        MaxReceivedMessageSize = 10000000

    var messageSecurity = new SymmetricSecurityBindingElement();

    var x509ProtectionParameters = new X509SecurityTokenParameters
        InclusionMode = SecurityTokenInclusionMode.Never

    messageSecurity.ProtectionTokenParameters = x509ProtectionParameters;
    return new CustomBinding(messageSecurity, httpTransport);

Note, I’ve increased the max message size to 10,000,000 bytes (10MB ish) because this is appropriate for my scenario.  You might want to think long and hard about doing this.  The default message size limit is relatively small to help ward off DDoS attacks, so think carefully before changing the default.  10MB is a lot of data to receive in a single request, even though it might not sound like much.

With the endpoint now exposed, a client (if we had one) would be able to connect.  Lets do some refactoring first to make our life a bit easier.


In the interest of simplicity, I haven’t worried too much about the client so far.  We need to make some changes to the project structure so that some of the lovely code we have written so far can be shared and kept DRY.  Add a class library to your project, called Shared and move the following classes into it (be sure to update the namespaces and add the appropriate reference).

  1. BindingHelper.cs
  2. IEchoService.cs
  3. EchoSecurityTokenSerializer.cs
  4. EchoConstants.cs
  5. EchoToken.cs

Client Side Implementation

We’re about 2/3 of the way through now.  Most of the leg work has been done and we just have to configure the client correctly so it can make first contact with the server.

Create a new console application (or whatever you fancy) and start by adding a reference to the Shared library you just created for the server.  Add the SSL certificate (CER format, doesn’t contain the private key) to your project as a resource.  Also add a reference to System.ServiceModel.

Custom ClientCredentials

The ClientCredentials works in a similar way to ServiceCredentials, but a couple of subtle differences.  When you instantiate the ClientCredentials, you want to pass it all the arbitrary claims you want to pass to the WCF service (License Key, Unique Code, User Name).  This object will be passed to the serializer that you created as part of the server side code (EchoSecurityTokenSerializer) later on.

First things first, create the EchoClientCredentials class as follows;

public class EchoClientCredentials : ClientCredentials
    public string LicenseKey { get; private set; }
    public string UniqueCode { get; private set; }
    public string ClientUserName { get; private set; }

    public EchoClientCredentials(string licenseKey, string uniqueCode, string userName)
        LicenseKey = licenseKey;
        UniqueCode = uniqueCode;
        ClientUserName = userName;

    protected override ClientCredentials CloneCore()
        return new EchoClientCredentials(LicenseKey, UniqueCode, ClientUserName);

    public override SecurityTokenManager CreateSecurityTokenManager()
        return new EchoClientCredentialsSecurityTokenManager(this);

The ClientCredentials has an abstract method CreateSecurityTokenManager, where we will use to tell WCF how to ultimately generate our token.

Client side Security Token Manager

As discussed, the ClientCredentialsSecurityTokenManager is responsible for “figuring out” what to do with a token that it has encountered.  Before it uses its own underlying token providers, it gives us the chance to specify our own, by calling CreateSecurityTokenProvider.  We can check the token type to see if we can handle that token ourselves.

Create a new class, called EchoClientCredentialsSecurityTokenManager, that derives from ClientCredentialsSecurityTokenManager, and add the following code;

public class EchoClientCredentialsSecurityTokenManager : ClientCredentialsSecurityTokenManager
    private readonly EchoClientCredentials _credentials;

    public EchoClientCredentialsSecurityTokenManager(EchoClientCredentials connectClientCredentials)
        : base(connectClientCredentials)
        _credentials = connectClientCredentials;

    public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
        if (tokenRequirement.TokenType == EchoConstants.EchoTokenType)
            // Handle this token for Custom.
            return new EchoTokenProvider(_credentials);
        if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement)
            // Return server certificate.
            if (tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate)
                return new X509SecurityTokenProvider(_credentials.ServiceCertificate.DefaultCertificate);
        return base.CreateSecurityTokenProvider(tokenRequirement);

    public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
        return new EchoSecurityTokenSerializer(version);

The code is pretty verbose, and we can see clearly what is happening here.  We can inspect the token type and see if it makes that of our Echo token.  If we find a match, return an EchoTokenProvider (coming next) which is just simply a wrapper containing our claims.  Note that we also are able to reuse the token serializer that we created as part of the server side work, a nice (not so little) time saver!

Security Token Provider

In this case, the security token provider is nothing more than a vessel that contains our client credentials.  The token provider instantiates the token, passes the client credentials, and passes the token off for serialization.

public class EchoTokenProvider : SecurityTokenProvider
    private readonly EchoClientCredentials _credentials;

    public EchoTokenProvider(EchoClientCredentials credentials)
        if (credentials == null) throw new ArgumentNullException("credentials");

        _credentials = credentials;

    protected override SecurityToken GetTokenCore(TimeSpan timeout)
        return new EchoToken(_credentials.LicenseKey, _credentials.UniqueCode, _credentials.ClientUserName);

Test Client

The client side code for establishing a connection with our service is relatively simple. We need each of the following:

  1. Define the endpoint (the address) of our service
  2. Create an instance of EchoClientCredentials
  3. Load the SSL certificate (the public key aspect at least) and pass to the credentials object we just instantiated
  4. Remove the default implementation of ClientCredentials and pass in our own
  5. Create a channel factory, and call our service method

Here is an example of what your client code would look like;

var serviceAddress = new EndpointAddress("http://echo.local/EchoService.svc");

var channelFactory = new ChannelFactory<IEchoService>(new BindingHelper().CreateHttpBinding(), serviceAddress);

var credentials = new EchoClientCredentials("license key", "unique code", "user name");
var certificate = new X509Certificate2(Resources.echo);
credentials.ServiceCertificate.DefaultCertificate = certificate;


var service = channelFactory.CreateChannel();

Security and Production Environment Considerations

Throughout this tutorial I have used HTTP bindings and told you explicitly not to use HTTPS, and there is a very good reason for that.  If you have a simple hosting environment, i.e. an environment that is NOT load balanced, then you can go ahead and make the following changes;

  • Change your service URL to HTTPS
  • Change HttpTransportBindingElement (on the server, inside the BindingHelper) to HttpsTransportBindingElement.
  • Add a HTTPS binding in IIS

Re-launch the client and all should be good.  If you get the following error message, you’re in big trouble.

The protocol ‘https’ is not supported.

After 4 days of battling with this error, I found what the problem is.  Basically WCF requires end to end HTTPS for HTTPS to be “supported”.  Take the following set up;


Some hosting companies will load balance the traffic.  That makes absolutely perfect sense and is completely reasonable.  The communications will be made from the client (laptop, desktop or whatever) via HTTPS, that bit is fine.  If you go to the service via HTTPS you will get a response.  However, and here’s the key, the communication between the load balancer and the physical web server probably isn’t secured.  I.e. doesn’t use HTTPS.  So the end-to-end communication isn’t HTTPS and therefore you get the error message described.

To work around this, use a HTTPS binding on the client, and a HTTP binding on the server.  This will guarantee that the traffic between the client and the server will be secure (thus preventing MIM attacks) but the traffic between the load balancer and the physical web server will not be secure (you’ll have to decide for yourself if you can live with that).


I’ve encountered a few quirks whilst developing this service over the last few weeks.  Quirks are things I can’t explain or don’t care to understand.  You must make the following changes to the server side code, or else it might not work.  If you find any other quirks, feel free to let me know and I’ll credit your discovery;


You must add the AddressFilterMode ‘Any’ to the service implementation, or it won’t work.

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]


A lot of work is required to be able to do custom authentication using ServiceCredentials with WCF, no fewer than 18 classes in total. For cases when a trivial User Name and password simply won’t suffice, you can use this approach. WCF works really well when developing non-web based applications, but the lack of documentation can make development and maintenance harder than it should be. Be careful when using in a load balanced environment, you may need to make some changes to your bindings as already discussed.

Publish your website to an IIS staging environment using Microsoft Web Deploy

One of the simplest and quickest ways to publish your website to a staging environment is, at least in my opinion, using Microsoft Web Deploy.  This post is about how you approach this, a future article will discuss why you probably shouldn’t do this.

Key points;

  1. The remote server should be running Internet Information Services (IIS) 7.0 or later.
  2. You can use the Microsoft Web Platform Installer to install all the extra bits you need to make this work.
  3. You need to set appropriate permissions to allow remote publishing.

Windows Server 2012 R2

On my local machine, for testing purposes, I have a Windows Server 2012 R2 virtual machine which is bare bones configured.

The first thing you need to do is install IIS.  You can do this using the Server Manager;

Open the Server Manager > click Add roles and features > select Role-based or feature-based installation > select the target server > and finally, select Web Server (IIS) and Windows Deployment Services.  Feel free to drill into each item and ensure you have the following selected (as well as whatever the defaults are);

  • Basic Authentication (very important)
  • ASP .NET 3.5 / 4.5
  • .NET Extensibility 3.5 / 4.5
  • IIS Management Console and Management Service (very important)

Once installed, you should be able to open IIS Manager by opening the Start menu, type inetmgr and press enter.

When IIS Manager opens (referred to herein as IIS), you should be prompted to download Microsoft Web Platform installer.  Ensure you do this.  Use the Web Platform installer to ensure you have all the following installed;

  • IIS 7 Recommended Configuration
  • IIS Management Service (should already be installed)
  • IIS Basic Authentication (should already be installed)
  • Web Deployment Tool (The current version is 3.5 at the time of writing, I also like to install Web Deploy for Hosting Servers as well)
  • Current version of the Microsoft .NET Framework
  • ASP .NET MVC 3 (as we will be publishing an ASP .NET MVC website)

I like to do a restart at this point, just to ensure that everything is tidied up (although I don’t think its 100% necessary, just ensure you restart IIS at the very least).

Enabling web deployment

The next step is to “switch on” the web management service.  This will allow remote users to connect up and deploy the website.

For the sake of simplicity, we will use basic authentication.  There are other means of authenticating users, but that is out of the scope of this tutorial.

AuthenticationIn IIS, select the server level node and then select the Authentication module (under the IIS grouping).

Simply right click on Basic Authentication, and the click Enable.

Next we need to configure the web management service to accept incoming connections.  Again, select the server level node, and select Management Service.

If the management service is already running, you need to stop it before continuing.  To do this, go to the Start Menu and type services.msc.  This will open the Services manager.  Search for Web Management Service, right click, and click Stop.  I ran through this process twice from scratch and the first time the service wasn’t running and the second time it was.  I not sure what triggers it to run.

Tick Enable Remote Connections and feel free to accept the default settings for now.  You could always revisit this later.  Click Start on the right hand side to start the service.

Configure your website

I’m sure you’ve done this many times before, so I will not regurgitate the details here.

Add a new website, give it a host name if you like, and specify the physical path (remember this).  Please ensure that you set the application pool to .NET CLR Version 4.0.30319 to avoid errors running the website further down the line.

Set the appropriate permissions for IIS_IUSRS

IIS requires read permissions to access the files that make up your website.  The simplest way is to head over to the physical folder for your website (that path you’re remembering from earlier), right click the folder, click Properties > Security > Edit > Add.  Type IIS_IUSRS then click Check Names.  Click OK, then OK to close the properties windows.

Create a Web Deploy Publish Profile

Finally, you can create a web deploy publish profile (simply an XML file with a few basic settings)  which you can import into Visual Studio to save you the hassle of having to type anything.

imageHead back over to IIS, right click on your website, click Deploy > Configure Web Deploy Publishing.

You can (and definitely should) create a restricted user account and grant permission to publish to that account (either an IIS account of a Windows authentication based account).

Once you have selected a user, click Setup.  A message should appear in the Results text area;

Publish enabled for 'WIN-DLICU73MRD0Jon'
Granted 'WIN-DLICU73MRD0Jon' full control on 'C:inetpubwwwroottestwebsite'
Successfully created settings file 'C:UsersJonDesktopWIN-DLICU73MRD0_Jon_TestWebsite.PublishSettings'

Success! This is your publish profile that you can import into Visual Studio.

Import your publish profile into Visual Studio

To import your publish profile, open your web solution and from the Build menu select Publish [your website].

PublishWebOn the Profile tab, click Import… and browse to the publish profile you just created.  Once imported, switch to the Connection tab and type the password for the account you selected earlier on the Configure Web Deploy Publishing dialog you saw earlier.

If you’re feeling lucky, hit the Validate Connection button.  All should validate properly.  If not, please refer to this little hidden gem from the IIS team to help troubleshoot any error messages you might be receiving.

Browse to your website using the host name you specified earlier (don’t forget to update your hosts file if you are “just testing”) and congratulations, after the initial feels like a lifetime compilation period, all should be good.

Next time you’re ready to publish, simply open the Publish dialog in Visual Studio, go straight to the Preview tab and hit Publish.  No more manual deployment for you my friend!


The Microsoft Web Deployment tool is a quick and convenient way to publish your website to a staging area for further testing.  You use the web deployment tool to generate a publish profile which can be imported into Visual Studio (saving you the hassle of having to type all that connection info)  and then call that service and pass it a package which will automatically deploy your site to the appropriate folders.

5 easy security enhancements for your ASP .NET application

Protecting web applications against unauthorised access is somewhat of a dark art, but there are simple steps you can take to ensure that you are protected against the most common security risks.

Cross Site Request Forgery (CSRF / XSRF)

Problem: Cross site request forgery (CSRF / XSRF) is the process of tricking a legitimate user of your website into posting data to the web server without their knowledge.  This type of attack is typically executed using a malicious link in an email, or by social engineering.

Typically, an attacker will craft a web page that has a form with fields named that match the properties that an ASP .NET MVC controller action method is expecting.  The form is then submitted (perhaps tucked away in an invisible iframe) and as long as the user has an active session open, the form will be processed as normal.  Such an attack could be as simple as posting a comment to a website without the users knowledge, or, say, in the case of a banking application, transfer money to the attacker.

Solution: To resolve the problem in ASP .NET MVC, you need to make use of  Anti-Forgery Tokens.  An anti-forgery token is a hidden field with a unique id that is placed on the form.  When the form is posted, the anti-forgery token is also passed along with the request and validated.  If the token is invalid, or missing, an exception is thrown.  Due to the random nature of the token, its impossible for an attacker to guess, meaning the only way to post to the server is via a page that originated from it.


In all your views that have forms that will be posted back to the server, simply use the AntiForgeryToken method on the HtmlHelper;

@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post))

Then add the ValidateAntiForgeryToken attribute to your action method;

public async Tas<ActionResult> Login(LoginViewModel model, string returnUrl)

Open Redirection

Problem: Open redirection is a form of phishing that, when a specific website is targeted, can be used to steal information, such as email address and password from a legitimate user.  The problem occurs when redirecting a user to a page based on information stored in the query string.  A malicious user could craft a URL to include a redirect to a website that looks identical to the original, which requests log-in credentials, then redirects the user back to the original website.

A user receives an email asking them to check out a page on a website, which they click.  The page requires the user to log in.  Rather than linking directly to the actual page, the link would point to the log in page, with a return Url;

Notice a very subtle difference between the source domain ( and the destination domain (  Easy to miss.  The user is prompted to enter their credentials, and they are then redirected to the returnUrl.  The user is actually shown an identical log in page which says that they have entered their credentials incorrectly, please try again.  The user re-enters the credentials and they are redirected back to the original site (which works because their credentials were correct in the first place).

This was a bigger problem in earlier versions of ASP .NET MVC because the vulnerability was present out-of-the-box.  The problem still exists when using the Redirect method in conjunction with the query string;


There are two solutions;

  • Don’t use the Redirect method at all.  Instead use RedirectToLocal or even better, use RedirectToRoute or RedirectToAction.
  • Only ever use hard coded return Urls when calling the Redirect method.

Cross Site Scripting (XSS)

Problem: Cross site scripting (XSS) is when an attacker uses a form on your website to inject script onto a page.  The script can be literally anything, from annoying popups/banner advertisements, to more sinister code designed to steal confidential information from a legitimate user.

By default in the current version of Razor (the ASP .NET MVC default view engine) all data originating from properties on your model is encoded.  Also, if a user tries to submit HTML / JavaScript using any forms on your website, an exception will be thrown and the data will be rejected.  The developer has to explicitly allow Html (using the aptly named AllowHtml attribute) or turn off validation (using the ValidateInput(false)) attribute.

If you absolutely have to accept Html on your website, make sure you implement a white list of allowed tags, rather than a blacklist of disallowed tags.

There is a lot of information available regarding this type of attack (as it is very common).  A good video I would suggest watching is The HaaHa Show: Microsoft ASP .NET MVC Security with Haack and Hanselman.

Over-posting (A.K.A. Mass Assignment)

Problem: It is possible to post additional data to the server along with a request, even for fields for which the developer never intended to be accessible by the client.  The problem is due to the fact that the model binder in ASP .NET MVC matches up all the post data to all problems on your entities/models without discrimination.

You have a Customer object, which contains details about a customer (Name, Address etc.).  You create a view for the user to edit their details, passing the Customer object to the view so that fields can be pre-populated.  When the user updates their details, and submits the form, the entity/model is saved back to the database.  However, your Customer object also has a navigation property called Orders, which contains all the orders that the customer has placed.  An attacker could submit a new order, which would be bound to the Orders property by the model binder, which may result in the customer receiving products that they haven’t actually paid for.


  1. Use the Bind attribute to either blacklist or whitelist properties on your entity/model.  The model binder will see the attribute, and either ignore or only bind the properties you have stated.
public void Save([Bind(Exclude = "Orders")]Entity entity)
{     //Logic
  1. Create a view model for each specific view, and only include the properties that you want exposed to the client (i.e. omit the Orders navigation property).

SSL for the login / registration process

Problem: SSL is required to ensure that confidential information, such as user credentials or credit card information is transferred from the clients web browser to your server in a secure manner.  Failure to do so will result in this information being susceptible to interception by a third party.

It is easy to see this information being posted to the server using a debugging proxy (such as Fiddler).

Example message sent from the browser (Google Chrome in this case) to a web server when attempting to log in to a website;

POST http://localhost:64429/Account/Login HTTP/1.1
Host: localhost:64429
Connection: keep-alive
Content-Length: 183
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:64429
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:64429/Account/Login
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: __RequestVerificationToken=dAaXZYTCsNTKUZT7cxKqTEVOXjii9Md-VzxfY9-XxcSW1C_3mEV7OK2Wrp_bbOsEB555GNWv7RK6p9soYpKljwtTsXL7zldikJB4aK-NYog1


Look closely, and you will see that the Request Verification Token includes the raw username/password;


Solution: You should purchase an SSL certificate and apply it to your website.  Doing so will encrypt the traffic so that it cannot be easily viewed between the source and destination.

If your website is hosted using Internet Information Services (IIS);

  • Open the IIS Manager (inetmgr.exe)
  • Select the root level node under “Connections”
  • Double click “Server Certificates”
  • Import the certificate using the links on the “Actions” pane
  • Click on your website
  • Add a new https binding and select the SSL certificate you just imported.