unity tag rich c# unity-container asp.net-identity

c# - tag - unity inspector separator



Registre IAuthenticationManager con Unity (5)

Estoy usando Unity for Dependencies Injection y el uso de Identiy Provider para administrar el inicio de sesión del usuario, el registro, la confirmación por correo electrónico, etc.

Cuando intento registrar un usuario, tengo este problema:

El tipo actual, Microsoft.Owin.Security.IAuthenticationManager, es una interfaz y no se puede construir. ¿Te estás perdiendo un mapeo de tipo?

No tengo idea de cómo registrar esta interfaz (IAuthenticationManager) en mi contenedor de Unity.

Intenté registrar la interfaz con este código, pero si lo digo, tengo otro problema:

No IUserTokenProvider está registrado.

container.RegisterType<HttpContextBase>( new InjectionFactory(_ => new HttpContextWrapper(HttpContext.Current))); container.RegisterType<IOwinContext>(new InjectionFactory(c => c.Resolve<HttpContextBase>().GetOwinContext())); container.RegisterType<IAuthenticationManager>( new InjectionFactory(c => c.Resolve<IOwinContext>().Authentication));

Puse un código de la aplicación (si no uso Unity, todo funciona bien):

AccountController

private IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } }

IdentityConfig.cs

public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store) { } public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) { var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); // Configure validation logic for usernames manager.UserValidator = new UserValidator<ApplicationUser>(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; // Configure validation logic for passwords manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, }; // Configure user lockout defaults manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); manager.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 in here. manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser> { MessageFormat = "Your security code is: {0}" }); manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser> { Subject = "SecurityCode", BodyFormat = "Your security code is {0}" }); manager.EmailService = new EmailService(); manager.SmsService = new SmsService(); var dataProtectionProvider = options.DataProtectionProvider; if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } } // Configure the RoleManager used in the application. RoleManager is defined in the ASP.NET Identity core assembly public class ApplicationRoleManager : RoleManager<IdentityRole> { public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore) : base(roleStore) { } public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context) { return new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>())); } } public class EmailService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Plug in your email service here to send an email. return Task.FromResult(0); } } public class SmsService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Plug in your sms service here to send a text message. return Task.FromResult(0); } } // This is useful if you do not want to tear down the database each time you run the application. // public class ApplicationDbInitializer : DropCreateDatabaseAlways<ApplicationDbContext> // This example shows you how to create a new database if the Model changes public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext> { protected override void Seed(ApplicationDbContext context) { InitializeIdentityForEF(context); base.Seed(context); } //Create [email protected] with password=Admin@123456 in the Admin role public static void InitializeIdentityForEF(ApplicationDbContext db) { var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>(); const string name = "[email protected]"; const string password = "Admin@123456"; const string roleName = "Admin"; //Create Role Admin if it does not exist var role = roleManager.FindByName(roleName); if (role == null) { role = new IdentityRole(roleName); var roleresult = roleManager.Create(role); } var user = userManager.FindByName(name); if (user == null) { user = new ApplicationUser { UserName = name, Email = name }; var result = userManager.Create(user, password); result = userManager.SetLockoutEnabled(user.Id, false); } // Add user admin to Role Admin if not already added var rolesForUser = userManager.GetRoles(user.Id); if (!rolesForUser.Contains(role.Name)) { var result = userManager.AddToRole(user.Id, role.Name); } } } public class ApplicationSignInManager : SignInManager<ApplicationUser, string> { public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { } public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) { return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); } public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) { return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); } }

¡¡Gracias!!


Esto es lo que hice para hacer que Unity juegue bien con ASP.NET Identity 2.0:

UnityConfig siguiente al método RegisterTypes en la clase UnityConfig :

container.RegisterType<DbContext, ApplicationDbContext>( new HierarchicalLifetimeManager()); container.RegisterType<UserManager<ApplicationUser>>( new HierarchicalLifetimeManager()); container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>( new HierarchicalLifetimeManager()); container.RegisterType<AccountController>( new InjectionConstructor());


Esto también funcionará como una configuración completa para permitir el uso de Unity con Identity 2.0:

container.RegisterType<MyDbContext>(new PerRequestLifetimeManager(), new InjectionConstructor()); // Identity container.RegisterType<UserManager<User>>(new HierarchicalLifetimeManager()); container.RegisterType<SignInManager<User, string>>(new HierarchicalLifetimeManager()); container.RegisterType<IUserStore<User>, UserStore<User>>(new PerRequestLifetimeManager(), new InjectionFactory(x => new UserStore<User>(GetConfiguredContainer().Resolve<MyDbContext>()))); container.RegisterType<IAuthenticationManager>(new InjectionFactory(x => HttpContext.Current.GetOwinContext().Authentication));

Con esta configuración, no necesitará registrar los tipos AccountController o ManageController con Unity.


Intente agregar debajo de la línea en la clase UnityConfig :

container.RegisterType<IAuthenticationManager>( new InjectionFactory( o => System.Web.HttpContext.Current.GetOwinContext().Authentication ) );


La reputación no me deja comentar, pero para agregar a la respuesta marcada user3849637s, para MVC con la Actualización 3, también deberá agregar ManageController ya que algunas funciones lo usan con el andamio actualizado:

container.RegisterType<ManageController>(new InjectionConstructor());


Si realmente desea usar Unity para administrar todas sus dependencias, puede intentar registrar también IAuthenticationManager en Unity

container.RegisterType<IAuthenticationManager>( new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));

Con algunas pequeñas adaptaciones, puede usar Unity para resolver todas las dependencias necesarias para Asp.net Identity.

Encontré una gran publicación sobre esto (también probé) aquí:

http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/