2

I am attempting to inject a UserFactory via Ninject, here is my binding:

  var u = new CurrentUserProvider(HttpContext.Current);
            kernel.Bind<ICurrentUserProvider>().ToMethod(context => u).InRequestScope();

This factory uses HttpContext to read a authentication cookie and populate a CurrentUser object, HttpContext is passed as a constructor parameter:

 public class CurrentUserProvider : ICurrentUserProvider
{
    public ICurrentUser CurrentUser { get; set; }

    public CurrentUserProvider(HttpContext context)
    {
        CurrentUser = GetCurrentUser(context);
    }

    private static ICurrentUser GetCurrentUser(HttpContext ctx)
    {
        var httpCookie = ctx.Request.Cookies[".ASPXAUTH"];

        if (httpCookie != null)
        {
            var cookie = httpCookie.Value;
            var ticket = FormsAuthentication.Decrypt(cookie);

            if (ticket != null)
            {
                var x = ticket.UserData.FromJson<CurrentUser>();
                ctx.Session["UserID"] = x.DatabaseName;
                return x;
            }
        }
        return null;
    }
}

However the HttpContext that gets passed into the UserFactory constructor is always null. This is a MVC4 project if that makes any difference to the approach.

Update: I have also tried the following code which does not error but my injected CurrentUserProvider property remains null:

 kernel.Bind<ICurrentUserProvider>().To<CurrentUserProvider>().InRequestScope()
            .WithConstructorArgument("context", ninjectContext => HttpContext.Current);
Simon
  • 6,062
  • 13
  • 60
  • 97
  • Well, first of all, you really shouldn't be re-decrypting the auth cookie like that, nor should you be using session to store the UserID information. You should instead be using a custom IPrincipal, such as defined here: http://peterbromberg.net/post/Implementing-a-Custom-IPrincipal-in-an-ASPNET-MVC-Application.aspx – Erik Funkenbusch Mar 14 '15 at 01:53
  • Thanks for the heads-up, I'll look into that. In this case I am not using membership but a bespoke authentication which writes a custom auth cookie. The cookie only stores non-sensitive data. – Simon Mar 14 '15 at 20:37
  • What does membership have to do with anything? IPrincipal is FormsAuthentication related, not Membership related. The example uses membership but you can use whatever you want instead. – Erik Funkenbusch Mar 15 '15 at 03:18
  • 1
    Also, have a look at http://stackoverflow.com/questions/27052029/null-user-on-httpcontext-obtained-from-structuremap/27075242#27075242 – NightOwl888 Mar 15 '15 at 03:36
  • Thanks @NightOwl888, your answers got me re-thinking my approach and I've now got it all working – Simon Mar 16 '15 at 11:03

2 Answers2

1

Thanks to NightOwl888 for pointing me in the right direction with this answer.

Instead of trying to work with HttpContext directly with Ninject, instead I have injected a factory object along these lines:

  public class AspNetUserContext : IUserContext
{
    public User CurrentUser
    {
        // Do not inject HttpContext in the ctor, but use it
        // here in this property
        get { return new User(HttpContext.Current.User); }
    }
}
Community
  • 1
  • 1
Simon
  • 6,062
  • 13
  • 60
  • 97
0

It looks to me like you are creating the CurrentUserProvider object too early. If you want it created at the time of binding, I believe you can update your code to be something like this:

    kernel.Bind<ICurrentUserProvider>().ToMethod(context => new CurrentUserProvider(context)).InRequestScope();
brader24
  • 485
  • 2
  • 10