If you are using cookie authentication in ASP.NET Identity 2.1, there are two timeout settings that look similar upon first glance, ValidateInterval and ExpireTimespan:
CookieAuthenticationOptions.ExpireTimespan is the option that allows you to set how long the issued cookie is valid for. In the example above, the cookie is valid for 30 minutes from the time of creation. Once those 30 minutes are up the user will have to sign back in becuase the SlidingExpiration is set to false.
If SlidingExpiration is set to true then the cookie would be re-issued on any request half way through the ExpireTimeSpan. For example, if the user logged in and then made a second request 16 minutes later the cookie would be re-issued for another 30 minutes. If the user logged in and then made a second request 31 minutes later then the user would be prompted to log in.
SecurityStampValidator Validation Interval
The validateInterval of the SecurityStampValidator.OnValidateIdentity function checks the security stamp field to insure validity of the cookie after the given internval. This is not the same as checking expiration of the cookie, although it can cause the same result of being logged out.
The Security Stamp is created anytime a password is created/changed or an external login is added/removed. If a user changes their password then the SecurityStamp will be updated. This results in any cookie that might have been issued previous to the password change to become invalid the next time the validateInterval occurs.
For a concrete example using the above settings (this is a unlikely example but gets the point across):
User signs in at location A.
Same User changes work stations and signs in 10 minutes later at location B.
Same User changes their password at location B at the 12 minute mark.
The Same user goes back the the work station at location A and issues a request at the 20 minute mark.
Since the User issued a request after the validateInterval at location A they will be signed-out and prompted for their credentials again.
When the user is signed out in this scenario it is different from the the cookie timing out because the 30 minute Expire Time Out was never reached. Yet the user is logged out because the validateInterval of the SecurityStampValidator.OnValidateIdentity was set to 15 minutes.
The differences
The difference is subtle at first glance but provides some great benefits, such as Sign-out Everywhere. But it can be confusing since the default ASP.NET Identity template only has validateInterval leaving the ExpireTimespan hidden and set to the default of 14 days. Without some digging a developer new to the ASP.NET Identity library might not immediately recognize that the validateInterval is not the same as expiring cookies on a given time fame.
This is another case for why naming things is hard. It might seem obvious to some but I definitely didn’t get this one right away, and I wasn’t the only one.
The LockoutEnabled flag in the ASP.NET Identity 2.0 model means that the user can be locked out, not that the user is locked out.
For a user to be locked out the LockoutEnabled must be true andLockoutEndDateUtc must be greater than the current date. To enable Locking out globally you must set UserLockoutEnabledByDefault to true on the UserManager:
publicstaticApplicationUserManagerCreate(IdentityFactoryOptions<ApplicationUserManager>options,IOwinContextcontext){varmanager=newApplicationUserManager(newUserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));// Enable Lock outsmanager.UserLockoutEnabledByDefault=true;manager.MaxFailedAccessAttemptsBeforeLockout=5;// if you want to lock out indefinitely 200 years should be enoughmanager.DefaultAccountLockoutTimeSpan=TimeSpan.FromDays(365*200);....}
This one was easy to figure out. Because the Microsoft ASP.NET Identity Team is tracking discussions publicly I was able find a work item with a google/bing search. At least they didn’t name it LockoutManager.
With the click of a few buttons we can have a scalable website set up in minutes. By linking a few hardware components together we can make plants sing and coffee pots that tweet.
Abstraction
Over the years the abstraction level at which we can build our projects has been increasing. We are seeing this at the hardware level and the software level.
At the hardware level, we have composable boards that we can leverage to do heaving lifting such driving motors and providing GPS.
At the software level the abstractions are being provided in the libraries we use. For example, with SignalR we can provide real time capability to our applications with out having to worry about the protocols every device supports. Another exciting set of libraries that is enabling us to write complex asynchronous code simpler is ReactiveX.
Internet of Things (IoT)
There is a buzz in the air right now about the Internet of Things (IoT). It is on everyone’s minds and there is quite a bit of hype. Although tweeting coffee pots catches the media’s attention, there will be a lot more IoT devices that provide a lot of value.
Along with highly available internet access, smaller/faster devices and a host other energy and power saving advances, the abstractions that have been built over the years is one of the key components that is bringing around the IoT revolution. We don’t have to worry about how to communicate with GPS satellites or how to design a scalable infrastructure, it has been done for us.
As developers this is an exciting time. We have some amazing tools to work with and we get to focus on how to bring these abstractions together in new and exciting ways.
In what ways will you bring the powerful abstractions together?
In the last post, we covered how to create a custom SigninManager. At first glance there was a lot of work to be down but after diving in we found that there were only a few simple classes we had to set up.
In this post, I will demonstrate how to use OWIN to load our SigninManager for each request. By the end of the post we will have a SigninManager that we can use to create an authentication cookie and sign a user into our system.
OWIN Middleware
The latest version of ASP.NET is setup to use the OWIN middleware. If we take a look the Startup.Auth.cs file in the App_Start folder we will find an example of the out-of-the-box SigninManager configuration:
publicvoidConfigureAuth(IAppBuilderapp){app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);//left other configuration out for brevity}
The app.CreatePerOwinContext<T>() creates one instance of the given type per request. This way we only have ApplicationUserManager and one ApplicationSignInManager around for each request. To configure our CustomUserManager and CustomSignInManager we need to create factory methods and add them to the Startup.Auth.cs.
It is important to note the order in which the app.CreatePerOwinContext<T>() is called in the configuration. Since a SigninManager requires a UserManger the call to create the SigninManager on the OWIN context must come after the call to create the UserManager
The app.CreatePerOwinContext<T>() can take two different types of methods (We will see each type of callback method when we create them):
Func<T> createCallback
Func<IdentityFactoryOptions<T>, IOwinContext, T>
UserManager Factory Method
The UserManager method is the first callback method type; a simple static method that returns a new CustomUserManager. It would be possible to configure a method that also returns the CustomUserDataContext and pass it to the store. To keep it simple and show both types of methods app.CreatePerOwinContext<T>() takes I have left it out.
And to use it in a Controller add the following property to the Controller class which uses the HttpContext to get our single instance per request. The private set allows you to create a Controller Constructor where you can pass a mock instance for testing.
[HttpPost][AllowAnonymous][ValidateAntiForgeryToken]publicasyncTask<ActionResult>Login(LoginViewModelmodel,stringreturnUrl){// do model validations, password compare and other checks then sign them in//creates and signs a cookie.CustomSignInManager.SignIn(customUser,isPersistent:true,rememberBrowser:false);}
Hope that helps clear up some of the steps that are required to create an authentication cookie against an existing database.
I have to admit when I first took a deeper look at the ASP.NET’s Identity model in version 2.1 I was a bit overwhelmed. I was looking for a way to authenticate a user against an existing database using Forms authentication to create an authentication cookie after verifying the user’s credentials. Looking at the template ASP.NET Individual User Accounts I found that the SignInManager was responsible for creating the authentication cookie and so I started there.
I found that the SignInManager constructor required a UserManager which in turned required an implementation of IUserStore. And so I went in search of a way to implement my own UserStore by look at the Entity Framework User Store. When I saw the number of interfaces Entity Frame works UserStore implemented I froze. Would I know what to implement and how?
IUser<TKey>
So I took a few deep breaths and when went back to the SigninManager. I would start there and see what was need to implement it. Using the existing SigninManager as a reference, I found I need to have a IUser<TKey>. This is easy enough:
The astute reader will have notice that we missed the implementation of the IUserStore<TUser> for the CustomerUserManager. This again is a very quick implementation of a few CRUD operations (I have left some of the implementation blank and the others are not production ready):
We have now implemented all the parts required to create a Custom SigninManager. The initial feeling of being overwhelmed with the number of interfaces to implement has gone away. It was actually quite simple to create all the pieces to create our own SigninManager. Stay tuned for the next blog post where I show how to hook it into the OWIN Middleware so we can use it to sign our user in and create our Authentication Cookie.