Customization Options With ASP.NET Identity

Thursday, January 9, 2014 by K. Scott Allen
6 comments

Identity and membership systems are difficult to implement because there is such a wide variety of business needs and technology requirements for these systems. Out of the box solutions for identity management will never make everyone happy and are guaranteed to make somebody angry.angry identity bird

Here are a few thoughts, pointers, and links revolving around customization options with the new ASP.NET Identity features.

But first, previous posts in this series:

1. For New Applications

The sweet spot for ASP.NET Identity is a greenfield application with minimal architectural constraints. If you are comfortable taking a dependency on the Entity Framework and aren’t trying to apply domain driven design to a complex problem space, the Identity framework is a quick approach to storing usernames, passwords, and logins.

By deriving from IdentityUser you can store custom profile properties per user. By deriving from IdentityDbContext you can add relationships between members and other data in a system.

2. For Existing Applications

Migrating existing applications to use the Identify framework is a bit trickier. You’ll need to provide some custom mapping for EF to work with an exiting schema, and also manage hashed passwords in a way that the Identity password hasher understands (which is extensible through an IPasswordHasher typed property on the UserManager class. Recently, a few articles appeared to help with this scenario:

The Identity framework doesn’t yet include all of the features of the previous membership frameworks, so you should perform a gap analysis before heading in this direction.

3. Using Identity 2.0 (And Integer Keys)

Based on feedback from the first release of the Identity framework, there is already a prerelease of Identity 2.0. Most notable in this release is the addition of an IUser<TKey> type, where TKey is the type of the primary key / identifier for a user. IUser<TKey> is useful for anyone who doesn’t like the default string type for a primary key. More information is available in the blog post Announcing preview of Microsoft.AspNet.Identity 2.0.0-alpha1, where you can also see the following improvements.

  • Account confirmation
  • Password Reset
  • Security Token Provider
  • Better Katana Integration
  • And more….

4. Ripping Things Apart

There are a number of good reasons to use the Identity framework’s UserManager class while implementing your own user store persistence logic.

For starters, implementing your own persistence logic in a scenario where you just need users with passwords, but not roles, claims, or 3rd party logins, is relatively straightforward. The UserManager can work with a class only implementing IUserStore and IUserPasswordStore, which require a total of 8 CRUD type methods. Following this path has a few benefits.

  • You don’t need to take a dependency on the Entity Framework in the assembly where you define a user
  • In fact, you don’t need the Entity Framework at all
  • The only constraint on a user is to implement IUser, which requires Id and UserName properties

The next post in this series will look at building a custom user store both with a relational and non-relational database.

5. Other Links and Ideas

Brock Allen’s analysis:  The good, the bad and the ugly of ASP.NET Identity

Khalid Abuhakmeh’s analysis: ASP.NET MVC 5 Authentication Breakdown and ASP.NET MVC 5 Authentication Breakdown : Part Deux

A database project template from Konstantin Tarkus to work with Identity in a DB first approach: ASP.NET Identity Database

A customization article by John Atten: Code-First Migration and Extending Identity Accounts in ASP.NET MVC 5 and Visual Studio 2013

6. Alternatives

Brock Allen’s Membership Reboot

Thinktecture’s IdentityServer 2

Experimenting with Forms and AngularJS

Monday, January 6, 2014 by K. Scott Allen
3 comments

The directives and controllers that AngularJS automatically associates with <form> and <input> elements offer quite a bit of functionality that is not apparent until you dig into the source code and experiment.

For example, in this plunkr I’ve created a simple HTML form with two inputs.

 <div ng-controller="registerController">
     
    <form name="registerForm" ng-submit="register()">
        
        <input name="username" type="text" placeholder="Username" 
               ng-model="username" required ng-minlength="3" />
        <input name="password" type="password" placeholder="Password" 
               ng-model="password" required />
        <input type="submit" ng-disabled="registerForm.$invalid"/>
            
        <div>{{message}}</div>
        <pre>{{ registerForm | alljson }}</pre>        
    </form>

</div>

Notice the form has a name. Giving a form a name means Angular will automatically associate the form with registerController’s $scope object. The associated property will have the same name as the form (registerForm) and contain information about input values, clean and dirty flags, as well as valid and invalid flags.

The plunkr will dump out the data available about the form using an alljson filter, defined below. I’m using a custom filter because the built-in Angular json purposefully ignores object attributes that start with $ (like $invalid).

app.filter("alljson", function() {
    return function(o) {
        return JSON.stringify(o, null, 4);
    };
});

The output will look like the following (some information omitted for brevity).

{
    "$name": "registerForm",
    "$dirty": true,
    "$pristine": false,
    "$valid": true,
    "$invalid": false,
    "username": {
        "$viewValue": "sallen",
        "$modelValue": "sallen",
        "$pristine": false,
        "$dirty": true,
        "$valid": true,
        "$invalid": false,
        "$name": "username",
        "$error": {
            "required": false,
            "minlength": false
        }
    },
    "password": {
        "$viewValue": "123",
        "$modelValue": "123",
        "$pristine": false,
        "$dirty": true,
        "$valid": true,
        "$invalid": false,
        "$name": "password",
        "$error": {
            "required": false
        }
    }
}

In addition to managing properties, Angular manipulates CSS classes in the DOM and provides extensibility points with model formatters and parsers,  We’ll look at these features in a future post.

ASP.NET Identity with the Entity Framework

Friday, January 3, 2014 by K. Scott Allen
16 comments

ASP.NET EF Identity In a previous post  (Core Identity), we saw how the .Core identity assembly provides interfaces for describing the data access needs of a membership and identity system. Core also provides a UserManager class with the domain logic for identity management.

The .EntityFramework identity assembly provides concrete implementations for the core interfaces.

Here are 5 things to know about how it all works together.

In A New MVC 5 Application

If you use File –> New Project to create an MVC 5 application with the “Individual User Accounts” security option, the new project template will spit out all the code needed for users to register, login, and logoff, with all information stored into a SQL Server database.

The new identity bits do not support some of the features included with membership providers in the years past, features like counting invalid login attempts and lockouts, but the extensibility is in place and the current implementation has some clean separations, so perhaps they’ll be in by default in the future.

Remember the UserManager is the domain logic, and the UserManager needs (at a minimum) an IUserPasswordStore to persist users and passwords. Thus, the way the default AccountController constructs a UserManager is by passing in a new UserStore, which implements IUserPasswordStore in addition to the other core identity interfaces for persisting claims, roles, and 3rd party logins.

new UserManager<ApplicationUser>(
    new UserStore<ApplicationUser>(
        new ApplicationDbContext()))

It turns out that UserStore also has a dependency, a dependency on an EF DbContext class, and not just any context but one that derives from IdentityDbContext. IdentityDbContext provides all of the EF code-first mapping and DbSet properties needed to manage the identity tables in SQL Server. The default “new project” code provides an ApplicationDbContext that derives from IdentityDbContext with the idea that you’ll add your own DbSet properties for the entities, tables, and overall data that your application needs and keep everything in the same database.

In short, an identity specific DbContext plugs into the concrete user store, which then plugs into the user manager.

Once all three are together you have an identity system that supports third party logins as well as local accounts.

In A New Web API or SPA Application

The WebAPI and Single Page Application project templates also support user registration and password logins, but in these templates the AccountController is an API controller that issues authentication tokens instead of authentication cookies. Because the identity management work happens inside both the AccountController and inside Katana middleware, a UserManager factory is responsible for creating the user manager that both the middleware and API controller share.

public static Func<UserManager<IdentityUser>> UserManagerFactory { get; set; }

This static property is in the Startup.Auth.cs file that holds the Katana Startup configuration class. The actual factory function is initialized in this class, also.

UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());

This code uses the default constructor for the UserStore class, which will create a new instance of an IdentityDbContext object since an object isn’t supplied. If you want to use your own IdentityDbContext derived class, like the MVC 5 project does, you can modify the above initialization code and pass in your own context.

Side note: the SPA application template produces more than 2700 lines of code to get started. Not a large amount, but there are structural design issues (like the static UserManagerFactory) that require a healthy amount of rework for real applications. My personal advice is to use the template to get some ideas, but throw the code away and start from scratch for production applications.

Connection Strings

By default, IdentityDbContext uses a connection string named “DefaultConnection”, and all the new project templates will include a DefaultConnection connection string in the project’s web.config file. The connection string points to a SQL Local DB database in the AppData folder.

To change the SQL Server database being used, you can change the value of the connection string in web.config. You can also pass a different connection string name into the DB context constructor.

The Easy Customizations

A new MVC 5 project (not the SPA or WebAPI templates) provides an IdentityModels.cs file with the following two classes.

public class ApplicationUser : IdentityUser
{
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {

    }
}

Remember ApplicationDbContext is the context used to initialize a UserStore for a UserManager. The context will already include Users and Roles properties it inherits from IdentityDbContext, but you can add additional properties to store movies, books, accounts, employees, or whatever an application needs to solve a problem.

The ApplicationUser class includes Id, Username, PasswordHash, and other properties it inherits from IdentityUser. You can add additional properties here to store additional profile information about a user.

For simple applications this all works well, but for more complex applications you again probably want to use the starting project template code only for inspiration and start your own implementation from scratch. The names, structure, and code organization all have a prototype code feel and aren’t production ready.

Managing Contexts

In a real application you’ll have to decide if you want to mingle your data context with IdentityDbContext. One issue to be aware of is that the UserStore class does not play well when using the unit of work design pattern. Specifically, the UserStore invokes SaveChanges in nearly every method call by default, which makes it easy to prematurely commit a unit of work. To change this behavior, change the AutoSaveChanges flag on the UserStore

var store = new UserStore<ApplicationUser>(new ApplicationDbContext());
store.AutoSaveChanges = false;

What’s Next

The new Identity system is easy for greenfield projects with no existing users, but quite a bit trickier if you have an existing schema or don’t use the Entity Framework. Fortunately, the separation of domain logic in the UserManager and persistence logic behind IUserStore and friends is a fairly clean separation, so it is relatively easy to implement a custom persistence layer. This is one of the topics we’ll cover in a future post.

Ten Years Of OdeToCode.com

Thursday, January 2, 2014 by K. Scott Allen
10 comments

The first article appeared here in December 2003, and just kept coming.

Quand on n'avance pas, on recule.

Agile 2014 Call For Papers

Tuesday, November 26, 2013 by K. Scott Allen
0 comments

David Starr and I are putting together a Development Practices and Craftsmanship track for the Agile 2014 conference. The conference is in Orlando next summer (July 28 – August 1).

From David’s post on the subject:

Both Scott and I want to bring this back to roots: Code. Software. Technical practices. You know, the stuff everyone wants to write index cards about. This track is for you, not your boss or your PM or your Scrum Master or anyone who doesn’t laugh at a good PInvoke() joke. And I want to hear from the awesome Elegant Code bloggers, commenters, and readers. You guys have amazing ideas. Let’s hear them.

SUBMIT YOUR TALK IDEAS HERE

ASP.NET Core Identity

Monday, November 25, 2013 by K. Scott Allen
11 comments

ASP.NET Core Identity AbstractionsThis release of Visual Studio 2013 and ASP.NET features YAMF - yet another membership framework. The new features build on top of an assembly and NuGet package named Microsoft.AspNet.Identity.Core.

The core identity abstractions are interface based and revolve around the concepts of users and stores. Users are the people who are happy to authenticate themselves to your web application, while stores are the components happy to persist and retrieve user information from a data source. 

These abstractions are more flexible and composable than the membership providers from previous releases of ASP.NET and don’t rely on the “membership provider” base classes that have been around since ASP.NET 2.0. 

In the next few blog posts we’ll look at how the components work, how to customize the identity features, how to work with 3rd party claims, and how to build a custom store using a non-relational database (specifically MongoDB).

This first post in the series looks at the core abstractions. It’s important to note that the Identity Core assembly defines mostly abstractions with no implementations. A later post will look at components provided by Microsoft to implement these interfaces and provide membership features backed by SQL Server.

IUser

A user object must implement the IUser interface, which requires every user to have at least an ID and a name. The most notable aspect of IUser is the Id property of type string. Strings work well for GUIDs but can be a bit tricky when using integers for keys as is common with SQL Server. More details in a future post.

IUserStore

The I*Store interfaces in the Core Identity assembly are factored to offer various levels of functionality.

IUserStore defines the bare minimum functionality you’d want for users – create, retrieve, update, and delete (CRUD) functionality. If your website wants to allow users to create local accounts with passwords, you’ll want a component implementing IUserPasswordStore (which is an IUserStore). For third party logins (Twitter and Facebook, for example), add in IUserLoginStore, and for claim storage there is an IUserClaimStore. Also, not shown in the class diagram above, is a collection of interfaces for roles (IRole, IUserRoleStore, etc). Let the debate on roles versus claims begin.

One of the curious aspects of IUserStore is its generic constraint.

public interface IUserStore<TUser> : IDisposable 
   where TUser : IUser
{
  // ...
}

The implication is that any user object you want to use with the Identity features will need to implement IUser, which requires a dependency on the core identity assembly. It’s a bit odd to place a constraint on an interface definition since an interface doesn’t provide an implementation, but presumably the constraint helps to enforce the concept of all users having username and IDs of type string. The method signatures for IUserStore make this assumption, as does the UserManager.

ASP.NET UserManagerUserManager

The UserManager is a concrete class and it is the UserManager that provides the domain logic for working with user information. The UserManager knows when to hash a password, when to validate a user, and how to manage claims.

There are a few extensibility points with the UserManager, for example, the manager has a number of properties you can use to set a custom user validator (any object implementing IIdentityValidator), a custom password validator, and a custom password hasher. The primary extensibility point is via the UserManager constructor, which allows you to pass in any object implementing IUserStore. If you want to use a UserManager to manage user information stored in SQL Server, we’ll look at pre-built classes to do this in a later post, but it is also easy to create an IUserStore to work with a document database or other forms of storage.

Remember an IUserStore doesn’t know how how to work with user passwords, only an IUserPasswordStore knows about passwords. The UserManager is aware of the different core interfaces and will try to work with the capabilities of the store object given in the constructor. For example, if you use FindByIdAsync the UserManager can use the user store to query for a user by ID, but if you invoke FindAsync (which takes a username and a password), and the underlying store doesn’t implement the IUserPassword store interface, the UserManager will be forced to throw an exception.

It’s tricky to use a single concrete class for everything from users to passwords to claims, and tradeoffs must be made. We’ll also look at some of the tradeoffs in upcoming posts.

Async

Something you might have noticed in the class diagrams is that every nearly every method on the store and manager classes is an async method. The return types for these methods are all Task<T>, where the Task represents the outstanding work of querying or updating user information.

These async methods work well with the Entity Framework version 6, which now includes an async API. We’ll also look at implementing these methods using a non-async data source in a future post.

Conclusions

The new Identity features are a welcome break from the dated model of the ASP.NET membership providers and more flexible than the the SimpleMembershipProvider in the last ASP.NET release.

Some developers will notice a lack of features compared to the membership providers of old (like the ability to track the last login and bad password attempts). Some of these features are easy to add, but it will be interesting to see the challenges that result if Microsoft attempts to add these features to the Identity bits in a future release (expect more interface definitions to appear).

Something I learned when building Memflex is that a membership framework has to make some assumptions and build itself around some core constraints which can limit the usefulness of a membership component in some applications – the needs for membership are just so varied in this big world. Still, the Identity bits have done a good job of abstracting away persistence concerns from the logic of managing users, logins, clams, and passwords, and as we’ll see in a future post (lots of future promises in this post), the implementation of the persistence APIs is mostly formulaic.

Shimming and Wrapping OWIN Middleware (Katana Part 5)

Wednesday, November 13, 2013 by K. Scott Allen
6 comments

Sometimes I’m not interested in what the OWIN pipeline is doing as a whole, but I’m trying to figure out what each piece of middleware is doing in the pipeline configured by someone else. This is useful, for example, when debugging which piece of middleware is grabbing a request and short-circuiting the pipeline by sending an immediate response.

What the following IAppBuilder can do is wrap a real IAppBuilder and add a middleware wrapper for every piece of middleware added to the real IAppBuilder.

It’s middleware-middleware mania!

public class WrappingAppBuilder<TWrapper> : IAppBuilder
{
    private readonly IAppBuilder _inner;
    private readonly object _wrappingOptions;

    public WrappingAppBuilder(IAppBuilder inner, object wrappingOptions)
    {
        _inner = inner;
        _wrappingOptions = wrappingOptions;
    }

    public IAppBuilder Use(object middleware, params object[] args)
    {
        _inner.Use(typeof (TWrapper), _wrappingOptions, GetDescription(middleware));
        return _inner.Use(middleware, args);
    }

    private string GetDescription(object middleware)
    {
        var type = middleware as Type ?? middleware.GetType();
        return type.Name;
    }

    public object Build(Type returnType)
    {
        return _inner.Build(returnType);
    }

    public IAppBuilder New()
    {
        return _inner.New();
    }

    public IDictionary<string, object> Properties
    {
        get
        {
            return _inner.Properties;
        }
    }
}

The wrapper is specified as a generic type parameter. The following wrapper will allow an external observer to inspect the environment dictionary before it goes into the next piece of middleware, and then again during the return.

using AppFunc = Func<IDictionary<string, object>, Task>;

public class WrappingLogger
{
    private readonly AppFunc _next;
    private readonly WrappingOptions _options;
    private readonly string _middlewareDescription;

    public WrappingLogger(
        AppFunc next, 
        WrappingOptions options, 
        string middlewareDescription)
    {
        _next = next;
        _options = options;
        _middlewareDescription = middlewareDescription;
    }

    public async Task Invoke(IDictionary<string, object> environment)
    {
        _options.BeforeNext(_middlewareDescription, environment);
        await _next(environment);
        _options.AfterNext(_middlewareDescription, environment);
    }
}

The above class is using the following options.

using LogFunc = Action<object, IDictionary<string, object>>;

public class WrappingOptions
{ 
    public LogFunc BeforeNext { get; set; }
    public LogFunc AfterNext { get; set; }
}

And configuration is as easy as:

public void Configuration(IAppBuilder app)
{
    var options = new WrappingOptions()
    {
        BeforeNext = (middleware, environment) =>
            Debug.WriteLine("Calling into: " + middleware),
        AfterNext = (middleware, environment) =>
            Debug.WriteLine("Coming back from: " + middleware),
    };

    app = new WrappingAppBuilder<WrappingLogger>(app, options);

    // ...
    // the rest of the middleware
}

The above options provide some very crude request logging, but with a little work you can watch for dictionary changes and add timing information.

Coming up soon: the new identity bits.

Previous posts in this series.

by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!