This blog has now officially moved into http://cibrax.me

Posted by cibrax

Once you write an OWIN Middleware service, it can be reused everywhere as long as OWIN is supported. In my last post, I discussed how you could write an Authentication Handler in Katana for Hawk (HMAC Authentication). Good news is NancyFx can be run as an OWIN handler, so you can use many of existing middleware services, including the ones that are ship with Katana.

Running NancyFx as a OWIN handler is pretty straightforward, and discussed in detail as part of the NancyFx documentation here. After run the steps described there and you have the application working, only a few more steps are required to register the additional middleware services.

The example bellow shows how the Startup class is modified to include Hawk authentication.

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseHawkAuthentication(new HawkAuthenticationOptions
        {
            Credentials = (id) =>
            {
                return new HawkCredential
                {
                    Id = "dh37fgj492je",
                    Key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn",
                    Algorithm = "hmacsha256",
                    User = "steve"
                };
            }
        });

        app.UseNancy();
    }
}

This code registers the Hawk Authentication Handler on top of the OWIN pipeline, so it will try to authenticate the calls before the request messages are passed over to NancyFx.

The authentication handlers in Katana set the user principal in the OWIN environment using the key “server.User”. The following code shows how you can get that principal in a NancyFx module,

public class HomeModule : NancyModule
{
  public HomeModule()
  {
    Get["/"] = x =>
    {
      var env = (IDictionary<string, object>)Context.Items[NancyOwinHost.RequestEnvironmentKey];

      if (!env.ContainsKey("server.User") || env["server.User"] == null)
      {
          return HttpStatusCode.Unauthorized;
      }

      var identity = (ClaimsPrincipal)env["server.User"];

      return "Hello " + identity.Identity.Name; 
    };
}
}

Thanks to OWIN, you don’t know any details of how these cross cutting concerns can be implemented in every possible web application framework.

Posted by cibrax
Filed under: , , ,

As I discussed in my previous post, Katana is pretty much organized in middleware services.  One of those middleware services is authentication, which provides some built-in implementations for existing OAuth providers such as Facebook, Twitter, Google or Microsoft, and also an implementation for Forms authentication with cookies.  All those implementations are currently distributed as Nuget packages under the name of Microsoft.Owin.Security.*, where the last part identifies the name of the implementation (e.g. Microsoft.Owin.Security.Twitter).

Microsoft.Owin.Security is also the core project where you can find the base classes for writing a new authentication handler, and the ones that all the these implementations use.

At first glance, the core class that you will use to create a new authentication handler is Microsoft.Owin.Security.Infrastructure.AuthenticationHandler<T>, where T is class that derives from AuthenticationOptions and contains all the properties for initializing the handler.

AuthenticationHandler<T> derives from Microsoft.Owin.Security.Infrastructure.AuthenticationHandler, which provides the following definition.

public abstract class AuthenticationHandler
{
   protected OwinRequest Request;
   protected OwinResponse Response;

   protected AuthenticationHandler();

   protected virtual Task ApplyResponseChallenge();

   protected virtual Task ApplyResponseCore();

   protected virtual Task ApplyResponseGrant();

   protected abstract Task<AuthenticationTicket> AuthenticateCore();
}

This class basically provides access to the current request/response OWIN messages, and also a few methods that can be overridden as part of the implementation.

  • ApplyResponseChallenge: This method can be overridden to send a authentication challenge when a middleware service in the upper layer denies the execution (e.g 401 status code). For example, this can be useful for basic authentication.
  • ApplyResponseCore: This method by default calls ApplyResponseChallenge and ApplyResponseGrant. It can be changed to make some additional processing of the Response message.
  • ApplyResponseGrant: This method is only useful for authentication methods that needs to implement sign-in/sign-out concerns such as OAuth or Forms authentication. You won’t be using this for some authentication options such as basic or hmac authentication.
  • AuthenticateCore: This is the more important method, and the one where all the main implementation of the authentication handler lives. The AuthenticationTicket will contain the identity of the authenticated user or null if the user couldn’t be authenticated.

The AuthenticationOptions base class only contains the following structure,

public abstract class AuthenticationOptions
{
  protected AuthenticationOptions(string authenticationType);

  public AuthenticationMode AuthenticationMode { get; set; }

  public string AuthenticationType { get; set; }

  public AuthenticationDescription Description { get; set; }
}
  • AuthenticationMode. It’s an enumeration with two possible values Active/Passive. It basically identifies the http flow for the authentication implementation. Some authentication methods like Basic or HMac are Active, so it can be used directly against the current request without requiring additional http redirections. Some other methods like OAuth or Forms are not, so those have to identified as Passive. This setting will affect the authentication middleware behaves, so you have to set the correct value for it.
  • AuthenticatinType. It represents the authentication scheme. For example, Basic.
  • AuthenticationDescription. It can be used to provide more information about the authentication method.

Only these two classes are used so far to create a new authentication handler. However, you will also need a another class that acts as a factory, and it is used to inject the handler into the OWIN pipeline. That class is Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware.

public abstract class AuthenticationMiddleware<TOptions> : OwinMiddleware where TOptions : Microsoft.Owin.Security.AuthenticationOptions
{
  public AuthenticationMiddleware(OwinMiddleware next, TOptions options);

  public TOptions Options { get; set; }

  protected abstract AuthenticationHandler<TOptions> CreateHandler();
}

This class basically receives the Options that must be passed to the AuthenticationHandler, and also contains a method CreateHandler where the handler is actually created.

I will use the rest of this post to describe the implementation of a handler for doing HMac authentication using Hawk.

The first step in the implementation is to create a custom AuthenticationOptions class.

public class HawkAuthenticationOptions : AuthenticationOptions
{
  public const string Scheme = "Hawk";

  public HawkAuthenticationOptions()
       : base(Scheme)
  {
   }

  public Func<string, HawkCredential> Credentials { get; set; }
}

The Credentials property is a callback that the authentication handler implementation will use to resolve the user/key to verify the HMAC received in the authorization header. In a Basic Authentication implementation, you could potentially have a callback or a reference to a repository to verify the username and password received in the authorization header. I am also passing “Hawk” as part of the constructor to set the authentication scheme associated to the handler.

The next step is to implement the AuthenticationHandler.

public class HawkAuthenticationHandler : AuthenticationHandler<HawkAuthenticationOptions>
{
  private readonly ILogger logger;

  public HawkAuthenticationHandler(ILogger logger)
  {
      this.logger = logger;
  }

  protected override Task<AuthenticationTicket> AuthenticateCore()
  {
     AuthenticationHeaderValue authorization = null;

     if (Request.GetHeader("authorization") != null)
     {
         authorization = AuthenticationHeaderValue.Parse(Request.GetHeader("authorization"));
      }

     if (authorization != null &&
          !string.Equals(authorization.Scheme, HawkAuthenticationOptions.Scheme))
     {
          this.logger.WriteInformation(string.Format("Authorization skipped. Schema found {0}",
               authorization.Scheme));

          return Task.FromResult(EmptyTicket());
      }

      if (authorization == null ||
         string.IsNullOrWhiteSpace(authorization.Scheme))
      {
          this.logger.WriteWarning("Authorization header not found");

          return Task.FromResult(EmptyTicket());
      }
      else
      {
          if (string.IsNullOrWhiteSpace(authorization.Parameter))
          {
              this.logger.WriteWarning("Invalid header format");
                    
              return Task.FromResult(EmptyTicket());
          }

         if (string.IsNullOrWhiteSpace(Request.Host))
         {
              this.logger.WriteWarning("Missing Host header");
                    
              return Task.FromResult(EmptyTicket());
          }

          try
          {
              var principal = Hawk.Authenticate(authorization.Parameter,
                   Request.Host,
                   Request.Method,
                   Request.Uri,
                   this.Options.Credentials);

              var identity = (ClaimsIdentity)((ClaimsPrincipal)principal).Identity;
              var ticket = new AuthenticationTicket(identity, (AuthenticationExtra)null);

              return Task.FromResult(ticket);
           }
           catch (SecurityException ex)
           {
                this.logger.WriteWarning(ex.Message);

                return Task.FromResult(EmptyTicket());
           }
        }
    }

    protected override Task ApplyResponseChallenge()
    {
         if (Response.StatusCode != 401)
         {
              return Task.FromResult<object>(null);
          }

         var ts = Hawk.ConvertToUnixTimestamp(DateTime.Now).ToString();
         var challenge = string.Format("ts=\"{0}\" ntp=\"{1}\"",
                ts, "pool.ntp.org");

         Response.AddHeader("WWW-Authenticate", HawkAuthenticationOptions.Scheme + " " + challenge);
         
        return Task.FromResult<object>(null);
     }

     private static AuthenticationTicket EmptyTicket()
     {
         return new AuthenticationTicket(null, (AuthenticationExtra)null);
      }
 }

The implementation is Active, so only overrides the AuthenticationCore and ApplyResponseChallenge methods. The AuthenticationCore implementation tries to locate a Authorization Header with a format that follows the Hawk specification to authenticate the call. If an Authorization header is not found or it can not be parsed, an AuthenticationTicket instance with an empty identity is returned. Otherwise, the identity is set in the ticket and returned as part of the task. This implementation also uses the logging facilities provided by Katana.

The last step is to implement the AuthenticationMiddleware class.

public class HawkAuthenticationMiddleware : AuthenticationMiddleware<HawkAuthenticationOptions>
{
    private readonly ILogger logger;

    public HawkAuthenticationMiddleware(
        OwinMiddleware next,
        IAppBuilder app,
        HawkAuthenticationOptions options) : base(next, options)
    {
         this.logger = app.CreateLogger<HawkAuthenticationHandler>();
     }

     protected override AuthenticationHandler<HawkAuthenticationOptions> CreateHandler()
     {
         return new HawkAuthenticationHandler(this.logger);
     }
 }

This implementation only overrides the CreateHandler method to return a new HawkAuthenticationHandler instance. As that instance relies on the Katana logger, the logger instance is first created from the IAppBuilder instance injected in the constructor.

Once you have the AuthenticationMiddleware implementation completed, you will want to inject it in the OWIN pipeline to use it in an existing application. An extension method can be provided to make this task easier for the developer.

public static class HawkAuthenticationExtensions
{
    public static IAppBuilder UseHawkAuthentication(this IAppBuilder app, HawkAuthenticationOptions options)
    {
        app.Use(typeof(HawkAuthenticationMiddleware), app, options);
        app.UseStageMarkerAuthenticate();
        return app;
     }
 }

The following example shows how this extension is used to register the HawkAuthenticationMiddleware service in an application that uses Web API with OWIN

public class Startup
{
     public void Configuration(IAppBuilder app)
     {
         app.SetLoggerFactory(new ConsoleLoggerFactory());

         var config = new HttpConfiguration();
         config.Routes.MapHttpRoute("Default", "api/{controller}");
            
         app.UseHawkAuthentication(new HawkAuthenticationOptions
         {
             Credentials = (id) =>
             {
                 return new HawkCredential
                 {
                     Id = "dh37fgj492je",
                     Key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn",
                     Algorithm = "hmacsha256",
                     User = "steve"
                 };
              }
         });
 
        app.UseWebApi(config);
            
     }
 }

All the code provided as part of this example for Hawk can be found in the HawkNet github project.

Posted by cibrax
Filed under: , , ,

Introduction

The .NET ecosystem offers today a lot of alternatives for developing web applications. You can either use any of the frameworks supported by Microsoft with ASP.NET such as Forms, MVC or Web API, or any other open source alternative like FubuMVC, ServiceStack, NancyFx or OpenRasta to name a few. From an architecture standpoint, all these frameworks have three main layers in common (in spite of the difference with the implementation details), hosting, middleware, and application.

The hosting layer is responsible for managing the underline process, where the http connections are established and managed, and also to materialize those connections into request/response objects that are sent to the upper layers. For example, the hosting layer could be ASP.NET running in IIS, or it could also be a console application that uses the http listener directly.

The middleware layer provides common infrastructure services, which runs at low level in the http stack, such as security, caching, or any other concern that can be handled at this level.

The application layer is where the applications or services are implemented using the features available in the framework.

However, the distinction between the middleware and application layers is not always clear, which causes that many of the middleware services end up being implemented in the application layer. For example, you could implement middleware services for security in ASP.NET MVC using filters, which rely on features specific to the application level in that framework. This make almost impossible to reuse all these services across all the available frameworks, so you will find different implementations of the same services for the different frameworks. To give an example, basic authentication is something that could be implemented as middleware service and reused, but today is implemented differently in each framework.

Someone would suggest that a ASP.NET Http Module could be a good option for implementing a middleware service, but that’s not necessarily true as it would only work when the hosting layer uses ASP.NET.

This exact problem is what OWIN specification tries to address by providing a common abstraction for any http-aware service or application with minimal dependencies on existing frameworks or implementations.  At very core level, OWIN defines a handler, which is represented as an application delegate,

using AppFunc = Func<
        IDictionary<string, object>, // Environment
        Task>; // Done

The idea is to represent the three layers discussed above as a set of handlers using the “chain of responsibility” pattern. The environment argument is a dictionary that the different handlers use to exchange values, and the next handler in the chain is represented with the task argument. Having said that, the first handler in the chain would be responsible for the hosting layer, and it should populate the environment with keys that describe the received http request message, such as scheme, port, request path, headers, etc. All those common headers are discussed as part of the specification.

Katana is a Microsoft implementation of the OWIN specification, which includes handlers for the hosting and middleware layers. It’s an open source project, which can be found in this location. All the investment that Microsoft has done so far for ASP.NET in the different application frameworks (i.e. MVC or Web API), it’s now being refactored as OWIN handlers that can be reused across different application frameworks. For example, cookie authentication or even OAuth are being implemented as middleware services that can be reused not only by ASP.NET web apps but also for other application frameworks in the open source world.

The application layer is also implemented as another OWIN handler, which is responsible for setting up all the infrastructure required to handle the request/response at the application level. You will find application handlers for ASP.NET MVC, ASP.NET Web API, SignalR, or NancyFx to give an example. 

Gettting Started with OWIN and Katana

The easiest way to get started with OWIN is to use the assembly distributed as nuget package. You will find a single nuget package for this called “OWIN”. This assembly only contains an interface IAppBuilder, which can be used to configure all the handlers that you want to use in your web application. This is a very low level interface that you won’t have to implement yourself if you use Katana.

In addition to the “OWIN” assembly, you will find two additional nuget packages

  • Owin.Extensions: Provides a set of very useful extensions methods for the IAppBuilder interface that you can use to configure the handlers.
  • Owin.Types: Provides a set of wrappers to represent the environment dictionary as a typed object representing the request and response messages.

You can implement your first OWIN handler using these three packages (You will not able to run it without the hosting handlers provided by Katana).

public class MyMiddleware
{
  Func<IDictionary<string, object>, Task> next;

  public MyMiddleware(Func<IDictionary<string, object>, Task> next)
  {
    this.next = next;
  }

  public Task Invoke(IDictionary<string, object> env)
  {
    var headers = (IDictionary<string, string[]>)env["owin.RequestHeaders"];

    var url = string.Format("{0}://{1}{2}{3}",
                (string)env["owin.RequestScheme"],
                headers["host"].First(),
                (string)env["owin.RequestPathBase"],
                (string)env["owin.RequestPath"]);

    if ((string)env["owin.RequestQueryString"] != "")
      url += "?" + (string)env["owin.RequestQueryString"];

    Console.WriteLine("The received URL is {0}", url);

    return this.next(env);
  }
}

This is a low level handler that sends the request url to the console. As you can see, it relies on some existing properties in the environment, which should have been set by Katana in the hosting layer. The handler also receives the next handler to call in the chain as part of the constructor.

The entry point in any Katana application must be a class that receives the IAppBuilder interface as argument to configure all the handlers, as it is shown below,

 public class Startup
 {
    public void Configuration(IAppBuilder app)
    {
       app.UseType<MyMiddleware>();       
    }
 }

UseType is one the extension methods provided by “Owin.Extensions” to configure a new handler in the pipeline. You can also other extension methods to define a handler on the fly using delegates as this one,

app.UseHandlerAsync(async (req, res) =>
{
    res.ContentType = "text/plain";
    await res.WriteAsync("Hello World");
});

There is one more nuget package that you will find useful to create OWIN handlers, which is “Microsoft.Owin”. This is a package provided as part of Katana (It’s still a pre-release), which extends the Owin Request and Response classes with more properties and methods, and also helper methods to deal with these classes.

Hosting an application with Katana

Katana provides three options to host a web application.

1. OwinHost.exe. It’s a command tool that you can use to run the application. You can use multiple command arguments to specify the assembly with the entry point for configuring the IAppBuilder or other configuration settings such as the port number or tracing. This is tool is available as part of the nuget package “OwinHost”.

2. .NET application. There is a WebApp class that you can use to self-host a web application in any regular .NET application such as console app or a windows service. This class is available as part of the “Microsoft.Owin.Hosting” assembly.

using (WebApp.Start<Startup>(new StartOptions { Port = 5000 }))
{
   Console.WriteLine("Press Enter to quit.");
   Console.ReadKey();
}

You need to pass the startup entry as argument to the static method “Start”.

3. ASP.NET. You need to reference the nuget package “Microsoft.Owin.Hosting.SystemWeb” (Pre-Release) from your web application project, and include the Startup class in that project as well.

Posted by cibrax
Filed under: , , ,

ETW or Event Tracing for Windows is a very efficient pub/sub built-in mechanism that runs in Kernel Mode for doing event tracing. That implies there is just a little overhead in using this feature compared to other traditional tracing solutions that are I/O bound and drop the traces in different storages like files or databases for example. As it is a built-in mechanism in Windows, many of the operating systems services and components make good use of it. You can not only troubleshoot your application but also many of the OS components involved in the execution of that application.

In ETW, you have applications publishing events in queues (or providers) and other applications consuming events from those queues in real-time through ETW sessions. When an event is published in a provider, it goes nowhere unless there is session collecting events on that queue. (The events are not persisted).

The adoption of ETW in .NET application was pretty low as it was very hard to configure and use. However, things might change now that .NET 4.5 supports a new EventSource class for publishing events easily in any .NET application. Another way to publish events in the past was to use .NET diagnostics infrastructure with the trace listener for ETW, “EventProviderTraceListener”.

About this last one, it can be easily configured and associated to a trace source as it is shown bellow,

<system.diagnostics>
  <sources>
    <source name="MyConsoleApp" switchValue="Verbose">
      <listeners>
        <add name="ETWListener" type="System.Diagnostics.Eventing.EventProviderTraceListener, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
               initializeData="13D5F7EF-9404-47ea-AF13-85484F09F2A7" />
      </listeners>
    </source>
  </sources>

  <trace autoflush="true"/>
</system.diagnostics>

The trace listener is associated to a GUID through the initializeData attribute. That identifier is used by ETW and associated to the provider, so it’s the one you will use to collect the events in a session.

Once the listener is configured, you can start publishing events in that provider through a the trace source.

TraceSource myTraceSource = new TraceSource("MyConsoleApp");

myTraceSource.TraceEvent(TraceEventType.Error, 1, "Tracing Error Message.");
myTraceSource.TraceEvent(TraceEventType.Warning, 2, "Tracing Warning Message.");
myTraceSource.TraceEvent(TraceEventType.Information, 3, "Tracing Information.");
myTraceSource.TraceEvent(TraceEventType.Verbose, 4, "Tracing Verbose Message.");
myTraceSource.TraceEvent(TraceEventType.Critical, 5, "Tracing Critical Message.");
            
myTraceSource.Close();

Listening for those events in a ETW session is a different story. The standard procedure is to use a set of tools for starting an ETW session and dump the events into a binary file with a proprietary format (these are “etl” files), that can be imported in the event log viewer or an specific tool for this kind of file. You also have a tool for converting “etl” files to more user readable formats like xml or cvs. However, you can also use the ETW unmanaged API to start a new session and subscribe to the events as it was done with the EventTraceWatcher implementation in this sample.

var providerId = new Guid("13D5F7EF-9404-47ea-AF13-85484F09F2A7");

using (EventTraceWatcher watcher = new EventTraceWatcher("MySession", providerId))
{
  watcher.EventArrived += delegate(object sender, EventArrivedEventArgs e)
  {
    if (e.Error != null)
    {
      Console.Error.WriteLine(e.Error);
      Environment.Exit(-1);
    }

    // Dump properties (key/value)
    foreach (var p in e.Properties)
    {
      Console.WriteLine("Event", "\t" + p.Key + " -- " + p.Value);
                        
    };

    // Start listening
    watcher.Start();

    Console.WriteLine("Listening...Press <Enter> to exit");
    Console.ReadLine();
}

You use the EventTraceWatcher to subscribe to events generated by an ETW provider, which are received as part of an event. What’s really interesting about this code is that it runs out of process. You could be collecting the events in a completely different application in the same host and doing whatever you want with those events like persisting them in a database for example. The performance of the application generating the events would not be affected at all.

Now, imagine that you have a service running in one of your servers, which can be used to start a new ETW session and publish those events via SignalR. In that way, you can connect with a browser to the SignalR hub created by that service and get the events realtime, which represents an interesting way to see what’s going on your server at a given time.

You can do an slight change to the code using the EventTraceWatcher to publish the events to a SignalR hub as it is shown bellow,

class Program
{
    static void Main(string[] args)
    {
        string url = "http://localhost:8080";

        using (WebApplication.Start<Startup>(url))
        {
            Console.WriteLine("Server running on {0}", url);
                
            var hubConnection = new HubConnection("http://localhost:8080/");
            var serverHub = hubConnection.CreateHubProxy("EventsHub");
            hubConnection.Start().Wait();

            var providerId = new Guid("13D5F7EF-9404-47ea-AF13-85484F09F2A7");

            using (EventTraceWatcher watcher = new EventTraceWatcher("MySession", providerId))
            {
                watcher.EventArrived += delegate(object sender, EventArrivedEventArgs e)
                {
                    if (e.Error != null)
                    {
                        Console.Error.WriteLine(e.Error);
                        Environment.Exit(-1);
                    }

                    // Dump properties (key/value)
                    foreach (var p in e.Properties)
                    {
                        serverHub.Invoke("PushEvent", "\t" + p.Key + " -- " + p.Value).Wait();
                    }
                };

                // Start listening
                watcher.Start();

                Console.WriteLine("Listening...Press <Enter> to exit");
                Console.ReadLine();
            }

            Console.ReadLine();
        }
    }
}

class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // Turn cross domain on 
        var config = new HubConfiguration { EnableCrossDomain = true };
            
        // This will map out to http://localhost:8080/signalr by default
        app.MapHubs(config);
    }
}
        
public class EventsHub : Hub
{
    public void PushEvent(string message)
    {
        Console.WriteLine("Event: " + message);

        Clients.All.PushEvent(message);
    }
}

This uses SignalR hosted in a console application with OWIN, so it could be literally moved to a windows service as well. Every time an event is captured from the ETW session, it is published in the SignalR hub.

On the other side, you can also use SignalR to subscribe to the same hub and receive the generated messages at real time.

<script type="text/javascript">
    $(function () {
        var messages = $('#messages');

        var connection = $.hubConnection('http://localhost:8080');
        connection.start()
            .done(function () {
                console.log("Connected, transport = " + connection.transport.name);
            })
            .fail(function () { console.log('Could not connect'); });

        var proxy = connection.createHubProxy('EventsHub');

        proxy.on('PushEvent', function (message) {
            messages.append(message + "<br>");
        });
    });
</script>

The code is available at Github, https://github.com/pcibraro/RealtimeTracing

Posted by cibrax
Filed under: , , ,

Some Web APIs use the client IP address to enforce Service Level Agreements such as limit the number of calls in a period of time. The client IP address can be used as a replacement for an authentication key sometimes when a previous registration of client applications is not required.

This is relatively simple to implement in a message handler,

public class IPThrottlingMessageHandler : DelegatingHandler
{
  IIPRepository repository;
  int maxRequestsHour;

  public IPThrottlingMessageHandler(IIPRepository repository, int maxRequestsHour = 150)
            : base()
  {
    this.repository = repository;
    this.maxRequestsHour = maxRequestsHour;
   }

   public IPThrottlingMessageHandler(HttpMessageHandler inner, IIPRepository repository, int maxRequestsHour = 150)
            : base(inner)
  {
     this.repository = repository;
     this.maxRequestsHour = maxRequestsHour;
   }

   protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
  {
     var ip = GetClientIp(request);
            
      if (ip == null)
      {
         return ToResponse(request, HttpStatusCode.Forbidden, "The client ip couldn't be found");
       }

       if(this.repository.Increment(DateTime.Now.Hour, ip) > this.maxRequestsHour)
       {
          return ToResponse(request, HttpStatusCode.Forbidden, "Quota exceeded");
        }
            
       return base.SendAsync(request, cancellationToken);
  }

  private string GetClientIp(HttpRequestMessage request)
  {
     if (request.Properties.ContainsKey("MS_HttpContext"))
     {
        return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
      }
     else if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
     {
        RemoteEndpointMessageProperty prop;
        prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
        return prop.Address;
      }
      else
      {
          return null;
       }
   }

   private static Task<HttpResponseMessage> ToResponse(HttpRequestMessage request, HttpStatusCode code, string message)
   {
       var tsc = new TaskCompletionSource<HttpResponseMessage>();

       var response = request.CreateResponse(code);
       response.ReasonPhrase = message;
       response.Content = new StringContent(message);

       tsc.SetResult(response);

        return tsc.Task;
    }
 }

This handler uses a repository to store the number of calls with a given IP in one hour. If the number of requests per hour exceeds the quota, an error response is returned to the client.

Posted by cibrax
Filed under: ,

Most of the Web APIs available out there in the web nowadays use some kind of authentication for identifying client applications. Although they implement authentication in different ways, they can be typically categorized in three main groups, services that use Keys, OAuth or HMAC.

Keys is the first scenario and probably the simplest one. Every client application is identified with a simple and fixed application key. This authentication mechanism is perhaps a bit weak, but the data that the service has to offer is not sensitive at all. The data is available for everyone with a key, and it’s pretty much used for public services such as Google maps or a search for public pictures in Instagram for example. The only purpose of the key is to identify clients and apply different SLA (service level agreements) such as api quotas, availability, etc.

HMAC is typically used for consuming sensitive data that is only consumed by his owner and not shared with anyone else. This kind of authentication is typically used in multitenant applications, where a tenant is the owner of the data. This model fits real well with cloud computing where a vendor such as AWS or Windows Azure use a key for identifying the tenant and provide the right services and private data. No matter which client application is used to consume the services and data, the main purpose of the key is to identify the tenant. Hawk is new specification born in this area to standardize how HMAC authentication.  

OAuth is last one and probably the most complicated one. It was born with the idea of delegating authorization in the web 2.0. The service who owns the data can use OAuth to share that data with other services or applications without compromising the owner credentials.

The analogy given by Eran Hammer Lahav in this post "Explaining OAuth" is very close to what the specification tries to address,

"Many luxury cars today come with a valet key. It is a special key you give the parking attendant and unlike your regular key, will not allow the car to drive more than a mile or two. Some valet keys will not open the trunk, while others will block access to your onboard cell phone address book. Regardless of what restrictions the valet key imposes, the idea is very clever. You give someone limited access to your car with a special key, while using another key to unlock everything else."

This kind of authentication makes a lot of sense in social media services like Twitter, Facebook, Windows Live or Google to name a few, where the service owns some private data like contacts or pictures that can shared with other applications without putting the user credentials into risk.

OAuth assigns a key to every different client application allowed to consume the data, so the access can easily be revoked by disabling the key associated that client application.

Posted by cibrax
Filed under: ,

One of the features supported by Hawk, an HTTP authentication protocol based on HMAC, is to provide read-only access to a Web API for a short period time.  That’s performed through a token called “bewit” that a Web API can provide to a client. That token is only valid for Http GET calls and it can be used for a limited period of time.

I already implemented this feature in my Hawk port for .NET. A bewit token can be generated as it is shown below,

var credential = new HawkCredential
{
     Id = "dh37fgj492je",
     Key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn",
     Algorithm = "hmacsha256",
     User = "steve"
 };

var bewit = Hawk.GetBewit("localhost", 
  new Uri("http://localhost:8091/Api/HelloWorld"), 
  credential, 
  60000);

The GetBewit method expects the following arguments,

  • The host name
  • The complete request URI
  • The Hawk credentials with information about the key and algorithm to use
  • A time-to-live setting in seconds for the token

That token is an string representation that you can add as a additional query string in the Web API call.

new HttpRequestMessage(HttpMethod.Get, 
  "http://localhost:8091/Api/HelloWorld?bewit=" + bewit);

In that way, you can share a link to your Web API with a limited access for a period of time to someone without having to share any security credentials.

On the service side is as simple as configuring the HawkMessageHandler as part of the Web API configuration,

var handler = new HawkMessageHandler((id) =>
{
     return new HawkCredential
     {
           Id = id,
           Key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn",
           Algorithm = "hmacsha256",
           User = "steve"
       };
 });

config.MessageHandlers.Add(handler);

The handler will automatically detect a bewit token in the query string, and it will performed all the required validations.

Posted by cibrax
Filed under: , ,

ASP.NET ships with two built-in mechanisms for doing logging and troubleshooting.  Chasing errors without knowing these two mechanisms might be a daunting task, specially if they happen in the runtime pipeline much before a message gets to a handler or a controller.

The first mechanism is the error policy. You can configure the error policy preferences as part of the configuration object (HttpConfiguration) in the IncludeErrorDetailPolicy property. This is just an enum that instructs Web API about how to deal with exceptions.

The possible values for this enum are,

  • Default: It’s uses the customErrors configuration settings if you are using ASP.NET as host or LocalOnly for self-host.
  • LocalOnly: Only includes error details for local requests
  • Always: Always includes error details
  • Never: Never includes error details

When an exception happens, Web API will check the value on this setting for including details about the exception in the response message or not. For example, if Always is enabled, Web API will serialize the exception details as part of the message that you get as response.

The second mechanism is Tracing. Tracing is a service that you can inject as part of the configuration object as well. The default implementation does do anything.

public static void Register(HttpConfiguration config)
{
    config.Services.Replace(typeof(ITraceWriter), new MyTracer());
}

MyTracer is a custom implementation of the ITraceWriter service, which Web API uses for tracing purposes. This is a general tracing mechanism, so Web API will call it for logging everything and not just errors.

public class MyTracer : ITraceWriter
{
    public void Trace(HttpRequestMessage request, string category, TraceLevel level, 
        Action<TraceRecord> traceAction)
    {
        TraceRecord rec = new TraceRecord(request, category, level);
        traceAction(rec);
        WriteTrace(rec);
    }

    protected void WriteTrace(TraceRecord rec)
    {
        var message = string.Format("{0};{1};{2}", 
            rec.Operator, rec.Operation, rec.Message);
        System.Diagnostics.Trace.WriteLine(message, rec.Category);
    }
}

If any of these two work for you, you can still use an Error Filter.  Tugberk has written a blog post about how to integrate ELMAH with an Error Filter in Web API here.

Posted by cibrax
Filed under: , ,

Message Handlers are one of the core components for message processing in Web API. They use an asynchronous model for processing messages, so they receive a request message and returns a Task with the corresponding response.

protected internal abstract Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
 CancellationToken cancellationToken);

In most cases, a message handler does something and delegates some other work to the rest of the handlers configured in the pipeline. For example, a handler for security checks the Auth Http header, and delegates the call the handlers configured out of the box by Web API, which eventually will call a controller method. The framework also provides a base class to make delegation implicit, DelegatingHandler, which receives the next handler to call as part of the constructor.

The following example shows a message handler implementation for basic authentication,

public class BasicAuthHandler : DelegatingHandler
{
   Func<string, string, IPrincipal> auth;

   public BasicAuthHandler(HttpMessageHandler innerHandler, Func<string, string, IPrincipal> auth)
       : base(innerHandler)
   {
       this.auth = auth;
    }

    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, 
System.Threading.CancellationToken cancellationToken)
    {
         if (request.Headers.Authorization != null &&
             !string.Equals(request.Headers.Authorization.Scheme, "basic", 
StringComparison.InvariantCultureIgnoreCase))
         {
              return base.SendAsync(request, cancellationToken);
          }

          if (request.Headers.Authorization == null ||
              string.IsNullOrWhiteSpace(request.Headers.Authorization.Scheme))
          {
              return ChallengeResponse(request);
           }

          var authToken = request.Headers.Authorization.Parameter;
          var decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken));

          var username = decodedToken.Substring(0, decodedToken.IndexOf(":"));
          var password = decodedToken.Substring(decodedToken.IndexOf(":") + 1);

          var principal = this.auth(username, password);
            
          if (principal == null)
          {
              return ToResponse(request, HttpStatusCode.Unauthorized, "Invalid credentials");
           }

          Thread.CurrentPrincipal = principal;
          if (HttpContext.Current != null)
             HttpContext.Current.User = principal;
                        
          return base.SendAsync(request, cancellationToken);
   }

   private static Task<HttpResponseMessage> ChallengeResponse(HttpRequestMessage request)
   {
       var tsc = new TaskCompletionSource<HttpResponseMessage>();

       var response = request.CreateResponse(HttpStatusCode.Unauthorized);
        response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("basic", "realm=localhost"));

       tsc.SetResult(response);

       return tsc.Task;
     }

     private static Task<HttpResponseMessage> ToResponse(HttpRequestMessage request, 
HttpStatusCode code, string message)
     {
        var tsc = new TaskCompletionSource<HttpResponseMessage>();

         var response = request.CreateResponse(code);
         response.ReasonPhrase = message;

         tsc.SetResult(response);

         return tsc.Task;
      }
 }

A good thing about Message Handler is that you can configure them globally or per route. In this case, if you want to enable basic authentication for some routes only, it’s a matter of configuring this handler in the routes you want to have protected.

config.Routes.MapHttpRoute(
   "BasicAuth",
   "MyController",
   new { controller = "MyController" },
   null,
   new BasicAuthHandler(new HttpControllerDispatcher(config), (u, p) => 
   {
      return new GenericPrincipal(new GenericIdentity(u, new string[] {}));
   }));

As you can see, the Inner Handler is a built-in handler provided by Web API, HttpControllerDispatcher, which does all the magic for processing the request and pass it over to the controller action. You can also inject any other dependency as part of the constructor. One thing to consider is that message handlers are singleton if you configure them this way, so make sure to inject the dependencies in the right way for avoiding memory leaks (If you have to use a repository for example, you might want to inject a factory or pass a delegate for resolving the dependencies from a DI container).

Posted by cibrax
Filed under: , ,
More Posts Next page »