Out of the box, Visual Studio 2013 comes with a number of templates for ASP.Net to cover most scenarios. The issue is that if you want registered users, you have a choice between Individual User Accounts, Organizational Accounts or Windows Authentication.
While "Individual User Accounts" sounds like the only option for apps that aren't using Azure AD or Windows Auth, the trouble is that it brings in all of ASP.Net Identity, which includes a local user database. If you look at the description above, it seems like this is the option to use for external/social logins, but as we'll discuss shortly, it's a red herring.
There are a few reasons why it's not a good idea to mix your user database with your main app:
- Single Responsibility Principle. This is the "S" in SOLID, and it applies to your application/service as a whole, not just your classes. Your application should be great at what it does. Your services should be granular and each do a single thing. Your app is the best thing since sliced bread. What it doesn't need, is to manage users.
- Security is hard. If you look at the template code generated by the ASP.Net wizards for "Individual User Accounts," you'll see tons of code in the
AccountControllerclass. Go ahead, take a look, I'll wait. Back yet? That code is now on you to understand and work with as after creation, it's no longer a library. As you go about adjusting the templates, and views, you need to make sure you don't accidentally introduce any issues. And you will need to be touching that code as the templates are not complete; they're a getting-started point.
- Higher Risk. Even though the password field in ASP.Net Identity is salted and hashed, there's still a lot of juicy information in your users table that a 1337 h@x0r would love to get their hands on. You don't want that 3am phone call.
Now that you're hopefully thoroughly convinced that you do not want to implement your own authentication, you're wondering what can you do now? The answer is to use an external authentication provider. Facebook is one, Microsoft Account another, and Google yet another. There's no shortage of external authentication providers these days. If you're thinking that "Individual User Accounts" with ASP.Net Identity does this for you (it's in the description and template code!), don't lose sight of the fact that it's really creating new identities in your app and simply linking external logins. See Brock Allen's detailed description on how it all works. It's the same core issue where your app is now managing identities.
Returning to that initial ASP.Net Authentication options dialog, there's one option that's conspicuously absent: External Identity Provider. This is one option that really needs to be present in the dialog—a set of templates that are geared around validating external claims that aren't part of Azure AD.
For Web API apps validating a Bearer token, this comes down to a single line of code (with Thinktecture's OWIN component):
With that one line, your Web API can rely on true external security.
To be clear, relying an an external provider does not mean that you need to give up the idea of having "local users," or multiple social logins like Facebook either. If you don't want to be tied to a single provider, you can use a service like Auth0 or an configurable identity app like Identity Server. Either of those options provides an appropriate architectural separation of concerns and lets the experts handle the authentication. Your app becomes a Relying Party to the external authentication service, receiving, and validating, a set of claims (such as an email address or unique user id in their system).
The key difference between ASP.Net Identity's assumptions and templates and using an external provider is who owns the claims. ASP.Net Identity translates external claims into its own identity system and issues its own new set of claims and tokens. My recommendation is that this extra layer is unnecessary and your application should use externally provided claims primarily.
There's one area that I haven't covered yet: what if you have your Web API and MVC content (even a SPA) in the same site? You'd like your login mechanism to work for both your web UI and your API. This is an area that has caused much confusion in current incarnations as Web API and MVC each do authentication a bit differently. For web browsers, you need some form of cookie auth while still having bearer tokens available for your API. This is exactly the situation I was in where I fell into the ASP.Net Identity trap. I'll talk more about what happened and how I solved it next time.
To sum up, if you're not sure whether to use ASP.Net Identity, this flow chat might help:
Special thanks to Barry Dorrans for reviewing this content prior to release.