There are many situations in enterprise IT that warrant securing particular WebAPI methods or even an entire controller. Suppose you had a web application with an administrator section that allows the provider of the application to create and manage records to which the End Users of the application only get read access.
In this post we will go over how you can lock down the back-end WebAPI to prevent direct usage of “administrative” APIs. The assumptions being made are:
First, we need to determine if the user invoking the request is a member of the Tenant that is the Provider of this application. This is actually easy to do through our SDK. The current RequestContext contains the ProviderId. We get to that RequestContext through the current SessionContext. The way I like to implement this is through an extension method, which allows me simply to ask, “Is the current Tenant the Provider of this application?” Here is what such an extension method would look like:
And then the usage would simply be:
We want a no-fuss method for implementing our method or controller-level WebAPI security. Luckily the .Net Framework provides us with the AuthorizeAttribute, which makes it very easy to implement your own special brand of security to suit your needs.
In our case, we would like to implement a [ProviderOnly] attribute that will allow execution only if the invoker belongs to the Provider. We will start with the full listing and then break it down.
As you can see, there really isn’t much to this. We name our attribute class ProviderOnlyAttribute so that we can leverage it simply by specifying [ProviderOnly] on the WebAPI controller or methods. This class inherits the base AuthorizeAttribute class and then overrides two key methods.
The OnAuthorization method will be invoked as part of the Authorization Filters in the ASP.NET Web API HTTP Message Lifecycle. The basic implementation is to check authorization using our helper method Authorize and either return if authorized or forward on to the unauthorized request handler.
The HandleUnauthorizedRequest method simply returns a 403 Forbidden in our example. As this is protecting a WebAPI, any other action, such as redirecting to a login page, just doesn’t make sense.
This is where our IsProvider extension method is put to good use. Using the Apprenda SDK we grab the current logged in user’s TenantContext and check to see if it is the Provider of the application. We also wrap this in a try/catch block to provide consistent handling in cases where even unauthenticated requests are sent without an active session.
With very little code we were able to create a powerful new attribute to hook into the Apprenda platform’s notion of multi-tenancy and secure our WebAPI. Here is an example controller that leverages this attribute to allow anyone to Get but then secures Post, Put, and Delete as Provider Only.
Any method tagged with [ProviderOnly] will now run through our custom attribute code, verify the invoking user’s Tenant is actually the Provider of the application, and then either let them through or return the 403 Forbidden. In practice I have found this to be an easy way to secure administrative functions of an API.
Questions or comments? Leave a note below or get in touch with us directly.