Simple API Key Authentication with ServiceStack

Reading time ~2 minutes

Sometimes you want to lock down your API to only allow certain clients access. I’d like to share a simple way of doing just that, based on HTTP headers and a simple pre-shared key.

Let’s just dive right in, shall we?

First thing’s first, let’s add a RequestFilter to perform the validation by extracting the key from a custom HTTP header:

// AppHost.cs
public class AppHost : AppHostBase
  public override void Configure(Container container)
    this.RequestFilters.Add((req, res, dto) => {
        var apiKey = req.Headers["X-ApiKey"];
        if (apiKey == null || !Clients.VerifyKey(apiKey))
          throw HttpError.Unauthorized("Unauthorized");

This static class we use to verify the key is valid, by checking against a custom ConfigurationSection (defined shortly):

// Clients.cs
public static class Clients
  private static Lazy<ClientSection> section = new Lazy<ClientSection>(() =>

  public static bool VerifyKey(string apiKey)
    return section.Value.Clients.Cast<ClientSection.ClientElement>()
           .Any(ce => ce.ApiKey == apiKey);

And the custom ConfigurationSection is as follows:

// ClientSection.cs
using System.Configuration;

public class ClientSection : ConfigurationSection
  public ClientElementCollection Clients
    get { return (ClientElementCollection)base["clients"]; }

  public class ClientElement : ConfigurationElement
    [ConfigurationProperty("apiKey", IsRequired = true)]
    public string ApiKey
      get { return (string)base["apiKey"]; }
      set { base["apiKey"] = value; }

    [ConfigurationProperty("name", IsRequired = true)]
    public string Name
      get { return (string)base["name"]; }
      set { base["name"] = value; }

  public class ClientElementCollection : ConfigurationElementCollection
    public override ConfigurationElementCollectionType CollectionType
      get { return ConfigurationElementCollectionType.BasicMap; }

    public ClientElement this[object key]
      get { return this.BaseGet(key) as ClientElement; }

    protected override ConfigurationElement CreateNewElement()
      return new ClientElement();

    protected override object GetElementKey(ConfigurationElement element)
      return ((ClientElement)element).Name;

    protected override bool IsElementName(string elementName)
      return !string.IsNullOrEmpty(elementName) && elementName.Equals("client");

As you can see, by far the largest class is the custom configuration section class. A necessary evil of .NET’s configuration system.

What this setup allows is to have the following in your web.config (or App.config if self-hosted):

<!-- [Web|App].config -->
<?xml version="1.0"?>
    <section name="apiClients" type="ClientSection" requirePermission="false"/>

      <client name="Client1" apiKey="somelongrandomkey" />
      <client name="Client2" apiKey="somelongrandomkey" />
      <!-- etc -->

Note: The <configsection> element needs a fully qualified type name, so if you need to put it in a namespace, make sure to include it in the type attribute.

Nice and easy client access management. All the client has to do is send the appropriate HTTP header. For example:

GET /json/reply/SomeRequest HTTP/1.1
X-ApiKey: somelongrandomkey

If you’re using the C# client, then it’s LocalHttpWebRequestFilter to the rescue:

// AuthenticatedJsonServiceClient.cs
public class AuthenticatedJsonServiceClient : JsonServiceClient
  public AuthenticatedJsonServiceClient(string baseUri)
    : base(baseUri)
    this.LocalHttpWebRequestFilter = req => {
      req.Headers.Add("X-ApiKey", "somelongrandomkey");

And that’s about it! Now, I realize that this might not be the most robust or ‘enterprise-y’ solution, but it’s simple, straightforward, and easy to manage.

You can also extend the ClientElement class if you need more per-client data. For instance, I’m currently selecting a connection string based on the ApiKey being sent over from the client:

// Added to the ClientElement class
[ConfigurationProperty("connectionStringName", IsRequired = true)]
public string ConnectionStringName
  get { return (string)base["connectionStringName"]; }
  set { base["connectionStringName"] = value; }

And in web.config:

<!-- web.config -->
<client name="Client1" connectionStringName="Client1DB" apiKey="somelongrandomkey" />

Actually retrieving the value of that property per-request I’ll leave as an exercise for the reader ;)

Happy coding!

ReactJS, or 'Why Client Side Is Fun Again'

A (hopefully) comprehensive walkthrough into ReactJS Continue reading

Programming the Infinity Keyboard

Published on February 25, 2015

Embedded Razor that doesn't suck

Published on November 25, 2014