Home > ASP.NET WebAPI, Azure, C#, Mobile Services > Authorization and public Help pages for Mobile Services written in .NET

Authorization and public Help pages for Mobile Services written in .NET

28/02/2014

Last week one of the most awaited feature for Azure Mobile Services has been released: the full support for writing backend logic using .NET and the ASP.NET Web API framework. We can now use Web API and Visual Studio to write, test and deploy our services. On Scott Guthrie’s blog you can read the official announcement, along with a step-by-step guide about how to use this new feature.

An interesting feature of this new support is that, because we’re working with a Web API, we can navigate to the /help page of the service to obtain the documentation of all the available methods (table functions, APIs, jobs). For each resource there are exanples of request and response messages, with a button that allows to directly invoke the function, so that it is easy to test the service.

This tool is very useful if we need to provide the documentation of our API to third parties, because all the pages are automatically generated for us.

However, it seems that the Help system only works when we execute the service within Visual Studio. In fact, after we have deployed the Mobile Service to Azure, if we try to access the /help page, we’ll obtain an HTTP erorr 403 – Forbidden. This is because, by default, all remote requests to mobile service resources are restricted to clients that present the application key.

In general, this behavior can be changed with the RequiresAuthorization attribute on contollers (or their methods). For example, we can use this attribute on a TableController like the following:

public class PeopleController : TableController<Person>
{
    [RequiresAuthorization(AuthorizationLevel.Anonymous)]
    public IQueryable<Person> Get()
    {
        ...
    }

    [RequiresAuthorization(AuthorizationLevel.User)]
    public async Task<IHttpActionResult> Post(Person item)
    {
        ...
    }
}

In this case, the Get method, that reads from the table, has anonymous access, while the Post operation, that performs an insert, requires an authenticated user. In other words, this attribute is used to specify the table methods permissions, like we do in the portal when we use Node.js for the backend.

The problem with Help is that it is provided by a class called HelpController that is part of the Azure Mobile Services SDK: so, like all the other controllers, once deployed it requires the application key, and this behavior cannot be changed because we don’t have direct access to the class (and so we can’t add a Custom Attribute to it). On the other hand, if we want to make the documentation of our service public, it must be accessed anonymously with a normal browser. Note that we have the same problem with ContentController, that is responsible for providing static content like CSS, Javascript, and so on.

The solution is to create a class that inherits from HelpController and another from ContentController, each of them with the anonymous authorization level:

[RequiresAuthorization(AuthorizationLevel.Anonymous)]
public class PublicContentController : ContentController
{
    [HttpGet]
    [Route("content/{*path}")]
    public new async Task<HttpResponseMessage> Index(string path = null)
    {
        return await base.Index(path);
    }
}

[RequiresAuthorization(AuthorizationLevel.Anonymous)]
public class PublicHelpController : HelpController
{
    [HttpGet]
    [Route("help")]
    public new IHttpActionResult Index()
    {
        return base.Index();
    }

    [HttpGet]
    [Route("help/api/{apiId}")]
    public new IHttpActionResult Api(string apiId)
    {
        return base.Api(apiId);
    }
}

As attribute routing takes precedence, we’re overwriting the default routes for /content and /help request, using controllers that allow anonymous access. We can now publish the Mobile Service to Azure and verify that the Help page can be correctly reached with a normal browser.

Note that the Help page of the deployed service has a different layout than the local one, but the information shown are the same (page layouts are embedded in the library). More important, even if the Help page is now public, other controllers mantain their own access rules, and so, for example, if we want to test a method of a TableController that has an Authorization level of Application (the default), in the Test Client Dialog we need to specify the Application Key of the Mobile Service using the X-ZUMO-APPLICATION header:

Azure Mobile Service Test Client Dialog

Azure Mobile Service Test Client Dialog

It is possible to refer to the official documentation for more information about this topic.

  1. Eugene Chuvyrov
    22/03/2014 at 09:28

    Thank you, this saved me at least a few hours of searching!

  1. No trackbacks yet.
Comments are closed.
%d bloggers like this: