While preparing a demo about Claims Based Authorization in .NET 4.5, I ran into an exception that initially had me dumbstruck. I created an ASP.NET MVC 4 application from the Internet template. Then I used the Identity and Access Tools for Visual Studio (downloadable from http://bit.ly/IDATVS2012) so users login through an external Identity Provider (for the demo LocalSTS). So far so good. Next I created a custom ClaimsAuthorizationManager class with a custom CheckAccess method to demonstrate how you can invoke this from code, essentially separating security checks from business logic. After hooking it up in web.config I run the code and after a wait I got an HttpException with the message Unable to connect to SQL Server database on a call to Principal.IsInRole, as you can see in the image below.
This had me puzzled to say the least. Why would a simple role check go to a database, especially because these are already in the Claims collection? First I tried commenting it out and just do a direct claim check… no dice. Why? The claims collection is empty. Huh? I have a page that lists the claims and they look fine. A closer look at the principal in the AuthorizationContext revealed it was actually of type System.Web.Security.RolePrincipal. That still inherits from ClaimsPrincipal, but it isn’t a normal ClaimsPrincipal, explaining the behavior. But now the big question: where did it come from? This took me a while to figure out with the help of a forum post (this one), ILSpy, and this blogpost by Phil Haack. As it turns out, the ASP.NET MVC 4 Internet template includes the WebMatrix.WebData DLL. This DLL, among other things contains classes used with the SimpleMembership API introduced by WebMatrix. SimpleMembership, which uses a database, is automatically enabled because the DLL uses PreApplicationStart method to initialize itself (as explained in Phil Haack’s blogpost). As soon as you place the WebMatrix.WebData DLL in your bin folder, it automatically registers itself. The result is that Thread.CurrentPrincipal yields a System.Web.Security.RolePrincipal instead of the ClaimsPrincipal associated with the user.
You could obviously remove the WebMatrix.WebData DLL, but there might be other functionality in there you want to use. A better option is to add the following key in web.config appSettings: