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:
With ASP.NET 4.5 it is very easy to enable users to login to your site with their accounts from Facebook, Google, LinkedIn, Twitter, Yahoo, and Windows Live. In this 7 part series I’ll show you how for each of the identity providers.
Note: Out-of-the-box this only works with WebForms and MVC4. MVC3 is not supported by default.
Part 5: Logging in with Twitter
As is the case with Facebook and LinkedIn discussed in previous posts, you need to register with Twitter. This means you have to get a Twitter account. With that account you have to register your application.
- Go to https://dev.twitter.com/apps and login with your Twitter account.
- Click the Create new application button.
- Fill out the form below. To avoid problems later, it makes sense to provide a Callback URL, even though it is not required.
- In the page above notice that Sign in with Twitter has the value No. If you would now try to login users into your application, your server would get a 401 Unauthorized exception. To change this, go to the Settings tab and scroll down to the Application Type section. There you can check the highlighted checkbox in the image below.
- Click the Update this Twitter application’s settings button.
- Open Visual Studio (if you don’t have already).
- Open the project created in Part 1 (or quickly create a project in the same manner).
- Find the App_Start folder and open AuthConfig.cs.
- Register the identity provider:
- In MVC go to the RegisterAuth method and uncomment the following line of code:
OAuthWebSecurity.RegisterTwitterClient( consumerKey: "", consumerSecret: "");
- In WebForms go to the RegisterOpenAuth method and uncomment the following line of code:
consumerKey: "your Twitter consumer key",
consumerSecret: "your Twitter consumer secret");
- Replace the place holder text with the Consumer key and Consumer secret shown on the Details page of your application in Twitter (see image under step 4).
- Save the file.
- Run the project.
- Click the Log in link. You will notice Twitter has automatically been added next to the other providers you added under Use another service to log in.
- Clicking the Twitter button will send you to Twitter to log in.
- Login with a Twitter account on the page shown below. Notice that it is telling the user which application wants you to log in with your Twitter account, and what the application can do once you logged in. Twitter recognizes the application from the Consumer key, and provides the user with the information you entered earlier.
- When you sign in you are automatically redirected to the application.