30 Days of Zumo.v2 (Azure Mobile Apps): Day 18 – ASP.NET Authentication

I introduced the ASP.NET backend in my last article, but it was rather a basic backend. It just did the basic TodoItem single table controller with no authentication. Today, I’m going to integrate the Azure Authentication / Authorization and adjust the table controller to produce a personal table – similar to the Node.js environment I posted about much earlier in the series.

If you followed along the journey so far, your backend is already configured for Authentication / Authorization. If you are using a new site for the ASP.NET backend, you may want to go back to Day 3 and read about setting up Authentication again.

Setting up the Project

The team has split the NuGet packages for Azure Mobile Apps up significantly so you only have to take what you need. You need to add the following NuGet packages to your project:

  • Microsoft.Azure.Mobile.Server.Authentication

You will also need to edit your App_Start/AzureMobile.cs file to take account of authentication:

using Owin;
using System.Configuration;
using System.Data.Entity;
using System.Web.Http;
using Microsoft.Azure.Mobile.Server;
using Microsoft.Azure.Mobile.Server.Authentication;
using Microsoft.Azure.Mobile.Server.Config;
using Microsoft.Azure.Mobile.Server.Tables.Config;
using backend.dotnet.Models;

namespace backend.dotnet
    public partial class Startup
        public static void ConfigureMobileApp(IAppBuilder app)
            HttpConfiguration config = new HttpConfiguration();

            // Configure the Azure Mobile Apps section
            new MobileAppConfiguration()
                    new MobileAppTableConfiguration()

            // Initialize the database with EF Code First
            Database.SetInitializer(new AzureMobileInitializer());

            MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();
            if (string.IsNullOrEmpty(settings.HostName))
                app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
                    SigningKey = ConfigurationManager.AppSettings["SigningKey"],
                    ValidAudiences = new[] { ConfigurationManager.AppSettings["ValidAudience"] },
                    ValidIssuers = new[] { ConfigurationManager.AppSettings["ValidIssuer"] },
                    TokenHandler = config.GetAppServiceTokenHandler()

            // Link the Web API into the configuration

I’ve got some extra packages to deal with. Then I need to set up authentication. The Authentication / Authorization provider requires me to configure it with JWT keys. Note that this is also how I could deal with custom authentication from a provider like Auth0 – just set up the signing key, audience and issuer and let Azure Mobile Apps deal with it.

Want to do local debugging with user authentication? Check out this blog post.

In order for the app settings to work, I need to add the app settings I am using to the web.config file:

    <add key="webpages:Version" value="" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="SigningKey" value="READ FROM AZURE"/>
    <add key="ValidAudience" value="https://{yoursite}.azurewebsites.net"/>
    <add key="ValidIssuer" value="https://{yoursite}.azurewebsites.net"/>

It actually doesn’t matter what value is there – the values will be overwritten by the Azure App Service when it runs. You can put your development values in there if you like.

Configuring a Table Controller

Now that I have configured the project, I can configure a table controller. This amounts to putting the standard [Authorize] attribute to the methods and/or controllers I want to authorize.

Note: One of the common problems is developers who say that “things are always authenticated, even if I don’t want them to be”. It’s likely you set the Authentication / Authorization setting to always authenticate – let anonymous connections through and you can then control which routes get authentications.

My personal table requires the entire table to be authenticated, so I just add the [Authorize] attribute to the entire class, like this:

namespace backend.dotnet.Controllers
    public class TodoItemController : TableController<TodoItem>
        protected override void Initialize(HttpControllerContext controllerContext)
            MyDbContext context = new MyDbContext();
            DomainManager = new EntityDomainManager<TodoItem>(context, Request);

The Personal Table DTO

My original DTO needs to be updated in preparation for the personal table:

using Microsoft.Azure.Mobile.Server;

namespace backend.dotnet.DataObjects
    public class TodoItem : EntityData
        public string UserId { get; set; }

        public string Text { get; set; }

        public bool Complete { get; set; }

Since this is Entity Framework, I would normally need to do an Entity Framework Code First Migration to get that field onto my database. You can find several walk-throughs of the process online. This isn’t an Entity Framework blog, so I’ll leave that process to better minds than mine. Just know that you have to deal with this aspect when using the ASP.NET backend. (Node deals with this via dynamic schema adjustments).

Dealing with Claims

When using the Azure Mobile Apps SDK, the User (technically, HttpContext.User) is available within your table controller. It’s specified as a ClaimsPrincipal and you can read it like this:

        private string GetAzureSID()
            var principal = this.User as ClaimsPrincipal;
            var sid = principal.FindFirst(ClaimTypes.NameIdentifier).Value;
            return sid;

I don’t want the Security ID. I want the email address of the user. To do that, I need to delve deeper:

        private async Task<string> GetEmailAddress()
            var credentials = await User.GetAppServiceIdentityAsync<AzureActiveDirectoryCredentials>(Request);
            return credentials.UserClaims
                .Where(claim => claim.Type.EndsWith("/emailaddress"))

The User.GetAppServiceIdentityAsync() method returns all the information contained in the /.auth/me endpoint, but placed into a class so you can deal with it. The claims are in the UserClaims property which returns an IEnumerable – a Claim is something with a Type and a Value. The email address is actually something like http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress – but it may be something else on Facebook, for example. To be reasonable, I just need the claim to end with emailaddress. The first one listed is the one I want.

Adjusting the controller response

I’m going to need to do some adjustments to the various endpoints in the table controller to use this.


The GetAllTodoItems() method uses the Query() method to construct a query based on the inbound OData query. I need to adjust that using something akin to LINQ to add a clause for the UserId:

        // GET tables/TodoItem
        public async Task<IQueryable<TodoItem>> GetAllTodoItem()
            Debug.WriteLine("GET tables/TodoItem");
            var emailAddr = await GetEmailAddress();
            return Query().Where(item => item.UserId == emailAddr);

There are lots of things you can do with a Query() object, so this is a great area for experimentation.


I can also use a similar query for the GetItem method:

        // GET tables/TodoItem/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public async Task<SingleResult<TodoItem>> GetTodoItem(string id)
            Debug.WriteLine($"GET tables/TodoItem/{id}");
            var emailAddr = await GetEmailAddress();
            var result = Lookup(id).Queryable.Where(item => item.UserId == emailAddr);
            return new SingleResult<TodoItem>(result);

The Lookup() method returns a Queryable with 0 or 1 entries. I then use LINQ to further filter based on the email address, before re-constituting the result into a SingleResult object. I find it’s easier to read (and test) when returning objects rather than IHttpActionResults. However, you can use whatever you are most comfortable with.

PatchItem and DeleteItem

The Patch and Delete are so close to one another that I combined them. I’ll take a look at the PATCH version – check the code for the DELETE version:

        // PATCH tables/TodoItem/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public async Task<TodoItem> PatchTodoItem(string id, Delta<TodoItem> patch)
            Debug.WriteLine($"PATCH tables/TodoItem/{id}");
            var item = Lookup(id).Queryable.FirstOrDefault<TodoItem>();
            if (item == null)
                throw new HttpResponseException(HttpStatusCode.NotFound);
            var emailAddr = await GetEmailAddress();
            if (item.UserId != emailAddr)
                throw new HttpResponseException(HttpStatusCode.Forbidden);
            return await UpdateAsync(id, patch);

In this version, I am doing the following logic:

  • Lookup the item – if it isn’t there, produce a 404 Not Found response
  • Does it belong to me – if not, produce a 403 Forbidden response
  • Update the record and return it


Finally, the PostItem is relatively easy:

        // POST tables/TodoItem
        public async Task<IHttpActionResult> PostTodoItem(TodoItem item)
            Debug.WriteLine($"POST tables/TodoItem");
            var emailAddr = await GetEmailAddress();
            item.UserId = emailAddr;
            TodoItem current = await InsertAsync(item);
            return CreatedAtRoute("Tables", new { id = current.Id }, current);

This version overwrites whatever the user supplied with the authenticated information.


When publishing, don’t forget to use a Code First Migration to get the extra field in the table. I must admit that I cheated here and just wiped out my database table. You can browse your database directly from Visual Studio. Open the Server Explorer, expand the Azure node (you will need to enter your Azure credentials), then expand the SQL Databases node. Finally right-click on the database and select Open in SQL Server Object Explorer.


You will have to enter the credentials for your SQL server. You will also have to permit your Client IP to access the database. Once you have done that, you can use Visual Studio to browse your tables and manage your data.

Next Steps

This is actually a huge step forward – I’ve now got equivalent functionality within both the Node.js and ASP.NET backends. I’ll continue to cover both Node.js and ASP.NET equally in the future. Next, however, I’m going to take a look at some final thoughts on ASP.NET controllers – things like soft delete, logging, and using existing tables. Until next time, my code is on my GitHub Repository.

One thought

  1. Pingback: Dew Drop – May 10, 2016 (#2248) | Morning Dew

Comments are closed.