Recently I have found an excellent question on Stackoverflow. The OP asks why does claim added to Idenetity after calling AuthenticationManager.SignIn still persist to the cookie.

The sample code was like this:

ClaimsIdentity identity = UserManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie );

var claim1 = new Claim(ClaimTypes.Country, "Arctica");
identity.AddClaim(claim1);

AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = true }, identity );

var claim2 = new Claim(ClaimTypes.Country, "Antartica");
identity.AddClaim(claim2);

Yeah, why does claim2 is available after cookie is already set.

Continue reading

I’ve spent a few hours trying to figure out why my code does not work, and I have not found any explanations to the issue, so might just write it down here.

In ASP.NET Identity there is a concept for user locking out. You can specify how many attempts user can gets before the lock-out kicks in and for how long the lockout is enabled. This is a widely known, from all the articles online. But what these articles don’t say is that users can be opted-in and opted-out from this process.

If you look on IdentityUser class, there are 2 fields that relate to lockout: LockoutEnabled and LockoutEndDateUtc. My first reaction was that LockoutEnabled says that user is locked-out and LockoutEndDateUtc is time when the lockout expires.

Turned out that I was wrong. LockoutEnabled is a flag saying that user can (or can not) be locked in principle. I.e. opt-in flag for locking. So if we have an admin user who we don’t want to lockout ever, we’ll set this flag to be false. And for the rest of user-base this should be set to true.

To check if user is locked-out use UserManager.IsLockedOutAsync(user.Id). Function UserManager.GetLockoutEnabledAsync() checks if user is opted in for lock-out, it does not check if user is actually locked-out.

And fields on IdentityUser – don’t use them to detect is user is locked out, they are lies! Use UserManager functions to detect user state.

Hope this will save some people a head-banging, cause that caused me some stress!

Update 27 Aug 2014

To enable locking-out UserManager should have these flags set:

//lockout users for 10 minutes
UserManager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(10);

// takes 6 incorrect attempts to lockout 
this.MaxFailedAccessAttemptsBeforeLockout = 6;

// when new user is created, they will be "lockable". 
this.UserLockoutEnabledByDefault = true;

To lockout user you can do this:

user.LockoutEnabled = true;
user.LockoutEndDateUtc = DateTime.UtcNow.AddMinutes(42);
await userManager.UpdateAsync(user);

This will set the user to be locked out for 42 minutes from now. However, this is not recommended way to lock-out user, this is what the framework does in the background. There are ways users can lock themselves out.

If you are updated to AspNet Identity 2.1 (which has been released recently). You should use SignInManager:

var signInManager = new SignInManager(userManager, authenticationManager);
var signInStatus = await signInManager.PasswordSignInAsync(username, password, isPersistent, shouldLockout);

If shouldLockout is true, user is getting locked out after a number of failed attempts to login.

PasswordSignInAsync method does the following steps:

  • checks if user with given username exists;
  • then checks if this user is not locked out;
  • if password is correct, redirects logic to 2FA (if it is enabled);
  • if shouldLockout is true, then on incorrect password increases number of failed log-ins on user record.

If you have not updated and still using Identity v2.0 do the following. On every failed attempt to login, call the following

await userManager.AccessFailedAsync(user.Id); 

IdentityUser class have property AccessFailedCount. The method above increases count on this property. If count is greater than UserManager.MaxFailedAccessAttemptsBeforeLockout, then user is getting locked out: user.LockoutEndDateUtc is set to a date in the future and resets AccessFailedCount to zero.

When user is signed-in successfully, you need to reset AccessFailedCount to zero. Do it by calling:

await userManager.ResetAccessFailedCountAsync(user.Id);

UPD July 2017: If you are looking to do User Impersonation in Asp.Net Core, read this article: http://tech.trailmax.info/2017/07/user-impersonation-in-asp-net-core/

Recently I’ve migrated my project to ASP.NET Identity. One of the features I had in the project is “Impersonation”. Administrators could impersonate any other user in the system. This is a strange requirement, but business behind the project wanted it.

This is the old impersonation way:

  1. When admin wanted impersonation, system would serialise information about admin account (mostly username).
  2. Find account for impersonated user
  3. Create a new authentication cookie for impersonated user
  4. As data add serialised information about admin account to the cookie
  5. Set the cookie
  6. Redirect admin to client page.
  7. Bingo, admin logged in as a client user.

To de-impersonate repeate the process in reverse. Get data about admin from cookie data (if it is present), delete cookie for client-user, login admin user again. Bingo, admin is logged in as admin again.

Here is the article how the old way is implemented

This exact code did not work with Identity framework. I tried finding the solution online, but nothing was available. My question on Stackoverslow immediately got 4 up-votes, but no answers. So people are interested in doing it, but nobody published any material on this. So here I am -)

Continue reading

We are hitting the deck with our site performance and optimisation. It is fast, but we want it uber-fast! So next stage is to have IIS up and active all the time with all the views being compiled and ready before any user comes to them.

By default, IIS compiles views only when a request for that view comes in. So first time a user visits some rare page in your application, user is waiting a bit longer while IIS does Just-In-Time compilation. And actually if you look under the hood IIS does stacks of things before it shows you a web-site.

Despite of common believe, IIS does not run your web-application from /bin folder, it copies all required files to a temp folder. To be more specific, it copies files to c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\. Reason for that – file locking. For just-in-time compilation, it needs to update binaries, but in /bin folder binaries can be locked.

Continue reading

HTTPS everywhere is a common theme of the modern infosys topics. Despite of that when I google for implementation of HTTPS in ASP.Net MVC applications, I find only a handful of horrible questions on StackOverflow, about how to implement HTTPS only on certain pages (i.e. login page). There have been numerous rants about security holes awaiting for you down that path. And Troy Hunt will whack you over your had for doing that!

See that link above? Go and read it! Seriously. I’ll wait.

Have you read it? Troy there explains why you want to have HTTPS Everywhere on your site, not just on a login page. Listen to this guy, he knows what he is talking about.

Continue reading

Note for yourself, when you are registering odata route in web-api configuration, it must be placed before the default catch-all route. I.e. :

Gloabal.asax.cs:

    protected void Application_Start()
    {
        // .. do stuff

        // This must be before registering all other routes    
        GlobalConfiguration.Configure(WebApiConfig.Register);

        AreaRegistration.RegisterAllAreas();

        RouteConfig.RegisterRoutes(RouteTable.Routes);

        // do other stuff...
    }

Of you place web-api route registration after MVC route registration, MVC routes will take priority and probably you won’t have OdataController in your MVC code.

And no, nothing magic about OData there, just standard routes registered in Asp.Net application.

After using MVC bundling and minification for a bit I run into a few problems. All of them are well known and will cause you trouble.

First of the problems I encountered – reordering of files in the bundle. When I add to bundle Main.css and then add MainOverrides.css I bloody-well mean it to stay in this order, cause overrides will not do anything if they are posted before the main file. Same goes to jquery and plugins.

Another issue I run into was image urls inside of css. When css files are bundled, they are output as:

<link href="/bundles/jquery-ui_css?v=U5E9COcCYIcH9HU1Qr9aiQotqSzLGT8YYDi6qhOpObk1" rel="stylesheet"/>

Continue reading

Being on holidays gives me a lot of time to go through MVC questions on StackOverflow. And a lot of questions come from misusing of ViewBag and ViewData. A lot of people leave out Model from MVC and just slap all their data into ViewBag. And this is bad.

I can understand why people are lazy: [sarcasm] creating an extra class can be very problematic, takes a lot of keystrokes [/sarcasm]. What people don’t realise is that ViewBag make them work harder.

ViewBag is a dynamic entity and it can contain any property it likes with any type it likes. So every time you do in controller something like this:

    public ActionResult SomeViewBagAction()
    {
        ViewBag.SomeText = "blah";
        return View();
    }

Continue reading

There are doubts about if you should test registrations in you IoC container. I have been intimidated by this blog-post for a while and did not touch container for writing our tests. However, we did have a problem in the past, when DI container could not create one of our controllers. And we have lost days trying to chase the problem – there was no meaningful error message, because the real exception was swallowed somewhere in transit. It turned out that we have violated DI principal of a simple constructor: “Do nothing in constructor”. I have blogged about this before.

Today I would like to show how we test our IoC container to check if it can create all our controllers. Because controllers are immediate aggregate roots that are used by an end user. And controllers in MVC are the final consumer in the dependency chain. So if you likely to hit a problem in a chain of dependencies, it is likely that you will catch it by creating all the controllers.

Of course, if you use IoC container as a service locator or Mediator pattern you will have to test container separately for the types you get out from container there (mostly Command Handlers and Query Handlers).

Continue reading