ASP.NET Identity and Windows Azure Table Storage
In case you haven’t heard, ASP.NET Identity is the new kid on the block for handling user identity, and replaces ASP.NET Membership, Simple Membership and Universal Membership. It is built on top of OWIN which positions it well for the future of ASP.NET. If you’re not familiar with ASP.NET Identity then check out Introduction to ASP.NET Identity by Pranav Rastogi or the posts by K. Scott Allen linked to at the bottom of the post.
In this post I’ll look at how to use Windows Azure Table Storage with ASP.NET Identity. One of the main objectives will be to make it easy to get started with using Table Storage with a web application created using the new templates in Visual Studio 2013.
Getting up and running
You will need to have a Windows Azure Storage account and an associated storage connection string . If you haven’t got a connection string then follow the instructions in How to use the Table Storage Service (see “Create a Windows Azure Storage Account” and “Setup a storage connection string”).
Armed with you storage connection string, start up Visual Studio 2013 and create a new ASP.NET Project with ASP.NET MVC:
Once the project has been created, open up Controllers\AccountController.cs. Notice that there is a using directive for Microsoft.AspNet.Identity.EntityFramework – this is the namespace that contains the default, Entity Framework implementation of the UserStore. The UserStore is created in the default constructor:
public AccountController() : this( new UserManager<ApplicationUser>( new UserStore<ApplicationUser>( new ApplicationDbContext()))) { }
Next we’ll install the NuGet package with the sample Table Storage implementation of UserStore. In the NuGet Package Manager Console (Under Tools\Library Package Manager), type
Install-Package leeksnet.AspNet.Identity.TableStorage
This will ensure that you have the Table Storage libraries as well as the sample UserStore for TableStorage. Now we just need to update the application to use it.
In AccountController, remove the using Microsoft.AspNet.Identity.EntityFramework and instead, add
using System.Configuration; using leeksnet.AspNet.Identity.TableStorage;
Now update the constructor we saw above:
public AccountController() : this( new UserManager<ApplicationUser>( new UserStore<ApplicationUser>( ConfigurationManager.ConnectionStrings["IdentityStore"].ConnectionString, id => id.GetHashCode().ToString(CultureInfo.InvariantCulture) ))) { }
We could have hard-coded the storage connection string in code, but it’s handy to have it in config as we can transform the setting when we publish. So we could use development storage locally, and the real Table Storage service when we deploy.
It’s also worth commenting on the lambda expression in the code above. When working with Table Storage, partition keys need to be considered. Partition Keys are an important part of how you scale Table Storage usage, but also how you enable querying of related data. For simplicity I’ve used the hashcode of the user id, but you can pick whatever strategy you want. If you wanted a fixed number of partitions, 10 say, you could use id%10 as the partition key.
Finally, add the your storage connection string to the web.config under the connectionStrings element, replacing the actual connection string with the one for your storage account. (And yes, I have regenerated my key since pasting it here!)
<add name="IdentityStore" connectionString="DefaultEndpointsProtocol=https; AccountName=aspnetidentitydemo; AccountKey=1dgL6+/FjNHx/y7Fo3LXVUB/cbMrD4XxYy2H+FQiTM3 jEBgzxvAed/72l7pvqrYDHj4CRHJEy5VlTalVji2ayA=="/>
Other Thoughts
Please note that this is a sample library and hasn’t been written with production usage in mind :-) My goal was to demonstrate how you could get started using Azure Table Storage with ASP.NET Identity. Not all of the ASP.NET Identity functionality is implemented, e.g. IUserClaimStore, IUserRoleStore. The implementation also couples the user ID and the user name as this simplifies the persistence a little – feel free to change it if that doesn’t suit you ;-) The source code is available at: https://github.com/stuartleeks/leeksnet.AspNet.Identity.TableStorage
If you haven’t got the Windows Azure SDK installed, then it is worth grabbing. Version 2.2 makes it simple to connect to your subscription, and you can view and update Table Storage contents (as well as obtaining storage connection strings) – see the announcement post for more details.
Further reading
If you want to read more about ASP.NET Identity then check out the asp.net/identity site.
K. Scott Allen nice also has a nice set of posts:
- ASP.NET Core Identity
- ASP.NET Identity with the Entity Framework
- Customization Options With ASP.NET Identity
Comments
Anonymous
January 15, 2014
Awesome, thanks! You meant "using directive" instead of "statement" in: "Notice that there is a using statement for Microsoft.AspNet.Identity.EntityFramework"Anonymous
January 15, 2014
@fredimachado - yes, good spot - I've updated that. Thanks!Anonymous
March 13, 2014
any chance of updating the example to include IUserEmailStore and IUserConfirmationStore?Anonymous
March 13, 2014
I've not looked at implementing those, but the email could be stored in the user table. I'd probably look at having an additional table to maintain the lookup from email to user idAnonymous
April 23, 2014
By doing this would it enable massive scalability in terms of number of users? I have been wondering what the limit to the number of users might be under SQL azure.Anonymous
May 29, 2014
Can we use this with ASP.Net Identity 2.0Anonymous
May 29, 2014
@Brent - the limit under SQL will depend on what tier of SQL Database you go with (and also what schema you use!) @Ravindra IIRC, ASP.NET Identity v2 adds a few fields to the user interface, so I think you need to add those (e.g. Email). You might also want to take a look at www.nuget.org/.../2.0.0-alpha3 Remember that this is sample-ware ;-)Anonymous
June 02, 2014
I was looking at your GitHub repository and i didn't see the 2.0.0-alpha3 updates. Are you tracking that work separately? I'm in prototyping out a 2.0 implementation and it would be instructive to compare notes.Anonymous
June 02, 2014
@Chris - apologies! A lot of this sort of code is done on trains and in hotels and I end up with poor source control habits :-( Apologies and confessions aside, I have now pushed up the changes in the v2 branch :-)Anonymous
April 11, 2015
Can this be used the same with a web api project as well? Your example uses the mvc project template.Anonymous
June 02, 2015
Please update this blog. We really need this work.Anonymous
June 02, 2015
@David - yes, this should work with Web API @John - as I called out in the closing paragraph of the article, this is really only at sample quality level. There are decisions to be made around how to handle multiple logins per user, roles, etc. The source is available on github if you want to use it as a starting point: github.com/.../leeksnet.AspNet.Identity.TableStorage Stuart