Search code examples
c#asp.net-mvc-5ninjectasp.net-identity-2ninject.web.mvc

Binding a ASP.Net Identity object to a Func using ninject


EDIT: I Found a solution but if anyone knows a better way I am all ears.

I am working on a ASP.Net MVC 5 application with some of ASP.Net Identity.

I have the following code (which is ran in Startup.cs on app start):

 public class Startup
{

    #region Properties/Delegates

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

    #endregion


    public void Configuration(IAppBuilder app)
    {



        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/auth/login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<UserManager<AppUserModel>, AppUserModel>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });


        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
        app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);


        // Configure the user manager
        // We use a delegate here so we can acess the IBuilder
        // Then we bind this delegate to UserManager<AppUserModel> in Ninject
        UserManagerFactory = () =>
        {
            var usermanager = new UserManager<AppUserModel>(
                new UserStore<AppUserModel>(new AppDbContext()));

            usermanager.PasswordHasher = new SQLPasswordHasher();

            // allow alphanumeric characters in username
            usermanager.UserValidator = new UserValidator<AppUserModel>(usermanager)
            {
                AllowOnlyAlphanumericUserNames = false
            };

            usermanager.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = true,
                RequireDigit = false,
                RequireLowercase = false,
                RequireUppercase = false
            };

            usermanager.UserLockoutEnabledByDefault = true;
            usermanager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
            usermanager.MaxFailedAccessAttemptsBeforeLockout = 5;

            // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
            // You can write your own provider and plug it in here.
            usermanager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<AppUserModel>
            {
                MessageFormat = "Your security code is {0}"
            });
            usermanager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<AppUserModel>
            {
                Subject = "Security Code",
                BodyFormat = "Your security code is {0}"
            });
            usermanager.EmailService = new EmailService();
            usermanager.SmsService = new SmsService();

            IDataProtectionProvider provider = app.GetDataProtectionProvider();
            if (provider != null)
            {
                IDataProtector dataProtector = provider.Create("ASP.NET Identity");

                usermanager.UserTokenProvider = new DataProtectorTokenProvider<AppUserModel>(dataProtector);
            }


            // use out custom claims provider
            //usermanager.ClaimsIdentityFactory = new AppUserClaimsIdentityFactory();

            return usermanager;
        };

    }

I would like to inject the UserManagerFactory above in the place of UserManager. I can not seem to get the binding to work.

What I have tried:

kernel.Bind<UserManager<AppUserModel>>().To<Startup.UserManagerFactory>();

What actually worked:

kernel.Bind<UserManager<AppUserModel>>().ToMethod(context => Startup.UserManagerFactory());

The UserManager is a object that Microsoft Identity owns.

I want to inject the Delegate into things like this:

private readonly UserManager<AppUserModel> _userManager;

    public AuthController(UserManager<AppUserModel> userManager)
    {
        this._userManager = userManager;
    }

This is based off of http://benfoster.io/blog/aspnet-identity-stripped-bare-mvc-part-2

Under Configuring UserManager and Authentication. He invoked it into the constructor I chose ninject instead.


Solution

  • Solved

    kernel.Bind<UserManager<AppUserModel>>().ToMethod(context => Startup.UserManagerFactory());
    

    Let me know if there is a better way!