Part 1: AspNet Identity and IoC Container Registration

Sounds like I’m making a series of articles about ASP.Net Identity and how to use it with Depenency Injection. Part 1 have seen a lot of hits from Google in just a few days. I suppose it is worth extending the tutorial.

Building up on Part 1 where I wired all Identity components to be injected by Unity container, now I’m going to add emailing service for email confirmation and password reset.

My plan is to use SendGrid as a email service and email debugging service Mailtrap.IO as a hosted fake SMTP server.

Continue reading

I’m reading a lot of blogs about development and .Net. One of the blogs I read is from Jimmy Bogard and one of the recent posts there is about guidelines for using Dependency Injection container.

I got involved in comments and one of the commenters was suggesting using Func<IFoo> as injection instead of injecting the instance for IFoo. And reasons for that were:

  1. The “captive dependency” problem… objects with more constrained lifetime being held by objects with longer->lived lifetime.

  2. The (wasteful) big-bang object graph problem… when an MVC action only requires 1 dependency, but the dependency graph for all dependencies within the controller need to be resolved.

  3. The occasional property injection… when its 2am and I don’t feel like fixing a circular dependency issue (don’t hate).

Continue reading

TL;DR: Registration code for Autofac, for SimpleInjector, for Unity, for Castle Windsor.

Tony Mackay has an alternative walk-through of a very similar process but with Autofac

Part 2: Sending Emails in Asp.Net Identity using Dependency Injection, Sendgrid and debugging it with Mailtrap.io

Warning: If you don’t know what Dependency Injection is or you don’t know why you need this, don’t waste your time on this article. This approach is not recommended for cases when you don’t need a IoC container and have only a handful of controllers. Visual Studio template with Identity framework works great out of the box. You don’t need DI to enjoy full power of Asp.Net Identity. This article does not explain what DI is, how it works and why you need it. So proceed with caution and only if you know the difference between constructor injection and lifetime scope.

I regularly monitor StackOverflow for questions related to AspNet Identity framework. And one question keeps popping up over and over again: how do you use Inversion of Control containers with this framework.

If you know the main principles of Dependency Injection, things are very simple. Identity is very DI-friendly and I’ve done a number of projects with Identity and injected all Identity components via Autofac or SimpleInjector. The principles behind DI are applicable to all the containers, despite the differences in API’s for registration.

For the sake of this blog-post I’ll start with the standard VS2013 template and use Unity container, just because I’ve never used Unity before. You can view registrations for SimpleInjector in my test-project.

Projects where I used Autofac are far too complex to show as an example and none of them are open-source, so Autofac fans will have to figure out themselves from my examples.

Continue reading

One other reader did send yet another interesting question. The conversation started about AspNet Identity, but the question is actually about Owin and how it works.

See this bit of code from HttpContextBaseExtensions

public static IOwinContext GetOwinContext(this HttpContextBase context)
{
    IDictionary<string, object> environment = GetOwinEnvironment(context);

    if (environment == null)
    {
        throw new InvalidOperationException(
            Microsoft.Owin.Host.SystemWeb.Resources.HttpContext_OwinEnvironmentNotFound);
    }

    return new OwinContext(environment);
}

Continue reading

Another question I’ve been asked about Identity.

Part of Startup class for Owin can be this:

public void ConfigureAuth(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        Provider = new CookieAuthenticationProvider
        {
            OnValidateIdentity = SecurityStampValidator
                .OnValidateIdentity<UserManager, ApplicationUser, int>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                    getUserIdCallback: (id) => (Int32.Parse(id.GetUserId())))
        },
    });
}

The question was “How does SecurityValidator.OnValidateIdentity invalidate all existing cookies” and “I understand that getUserIdCallback delegate returns an id of a user, but I don’t quite see the usefulness of this parameter” and “why the need for regenerateIdentityCallback parameter“.

Continue reading

I’ve been reached out by one of my readers with a list of questions about AspNet Identity. First I thought the questions will be easy and I’ll wing them, but turned out that every single question in the list is worth of a separate blog post. So I’ll do a mini-series of Q-A posts about Identity framework and related stuff.

First question is about security token in a Cookie and how it is computed: Identity Framework creates a token in the cookie, token containing the same information (User.Id, Security Stamp, etc.); if the same user loggen-in in Chrome and Firefox, why are the cookies different?

I did think about it for a while, I guessed that cookie creation and expiration is encoded in the cookie, along with some sort of signature of the cookie. My guess was not far from the real world.

Fortunately, the code that deals with cookies is in Katana Project and is open-sourced.

Continue reading

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

When I’d like to find out about technologies used on the site, I look on HTTP header, then on cookies. Usually combination of these can give me a pretty detailed information about underlying technology used. Cookie names are very bad for that – search for any cookie name and you’ll get a lot of information about the technology.

To hide yourself, you can rename cookies from standard to something random. In Asp.Net Identity you can do that via CookieName property on CookieAuthenticationOptions class in configuration:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<UserManager, ApplicationUser>(
            validateInterval: TimeSpan.FromMinutes(0),
            regenerateIdentity: (manager, user) => manager.GenerateUserIdentityAsync(user))
    },
    CookieName = "jumpingjacks",
});

See the jumpingjacks string? that will be the cookie name when users login. You can find the full project source code in my Github repository

There are plenty of articles about how to deploy a solution to Azure Web-Sites. I’ll just leave this here for myself:

msbuild .\SolutionName.sln /p:DeployOnBuild=true /p:PublishProfile=ProfileName /p:Password=passwordForAzurePublishing /p:AllowUntrustedCertificate=true

This builds solution according to previously configured Publish Profile.

  • Good thing that all the configurations parameters are stored within Profile, where you can tell the thing to pre-compile the views and publish to folder where you need it.

  • Bad thing – you can’t specify where deploy to, as that is specified in the Publishing Profile. But you can configure different profiles to publish to testing and to production.

  • Another very bad thing – you can’t provide it with a pre-built web-deploy package, this builds the solution again every time you execute it. And this breaks the rule of Continuous Integration and Deployment: “Build once, deploy everywhere”. Suppose you have a Build Server with process that looks like this: Build => Run Unit Tests => Run Integration Tests => Deploy to Testing => Deploy to Production. And if for deployment you use the line I quoted above, you will be compiling your sources 3 times: first time to run tests, then every time to deploy. In some sense this is OK, because you are building from the same sources, but this is a waste of time. If I build my application with pre-compiled views, this can take a while. One of the applications I work on has 800 views and compilation of all these views takes about 7 minutes. If I compile them once, and re-use that, I don’t need to wait another 7 minutes for deployment to production. Well, OK, OK! Msbuild has got some clever stuff in it and probably will not re-compile all the views if nothing have changed and second time it’ll take less time to do compilation, but that still bothers me. Hopefully new Asp vNext will do something to make my life easier in this sense.

UPD: Here is another good solution to this problem if you are running your own IIS.

Last week I was updating one of applications I work on to ASP.NET Identity. For a specific reasons I could not deploy to Azure for a while. But I did run all the tests locally and everything worked just fine.

When I mostly finished with Identity conversion, I finally managed to deploy the application to Azure Web-Sites. And it worked fine.. until I tried registering a user.

At that point I had an exception exploding in my face:

System.Security.Cryptography.CryptographicException: The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context, which may be the case when the thread is impersonating.

Continue reading