J'utilise Unity for Dependencies Injection et j'utilise Identiy Provider pour gérer la connexion utilisateur, l'inscription, la confirmation par e-mail, etc.
Lorsque j'essaie d'enregistrer un utilisateur, j'ai ce problème:
Le type actuel, Microsoft.Owin.Security.IAuthenticationManager, est une interface et ne peut pas être construit. Vous manquez un mappage de type?
Je ne sais pas comment enregistrer cette interface (IAuthenticationManager) dans mon conteneur Unity.
J'ai essayé d'enregistrer l'interface avec ce code, mais si je le mets, j'ai un autre problème:
Aucun IUserTokenProvider n'est enregistré.
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));
Je mets du code de l'application (si je n'utilise pas Unity, tout fonctionne 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);
}
}
Merci!!
Voici ce que j'ai fait pour que Unity joue Nice avec ASP.NET Identity 2.0:
J'ai ajouté ce qui suit à la méthode RegisterTypes
dans la classe 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());
Essayez d'ajouter la ligne ci-dessous dans la classe UnityConfig
:
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(
o => System.Web.HttpContext.Current.GetOwinContext().Authentication
)
);
Cela fonctionnera également comme une configuration complète pour permettre l'utilisation d'Unity avec 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));
Avec ce paramètre, vous n'aurez pas besoin d'enregistrer les types AccountController ou ManageController avec Unity.
Si vous voulez vraiment utiliser Unity pour gérer toutes vos dépendances, vous pouvez essayer d'enregistrer également IAuthenticationManager dans Unity
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
Avec quelques petites adaptations, vous pouvez ensuite utiliser Unity pour résoudre toutes les dépendances nécessaires pour Asp.net Identity.
J'ai trouvé un excellent article à ce sujet (également testé par moi) ici:
http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/
La réputation ne me laissera pas commenter, mais pour ajouter à la réponse marquée user3849637s, pour MVC avec la mise à jour 3, vous devrez également ajouter ManageController car certaines fonctions l'utilisent avec l'échafaudage mis à jour:
container.RegisterType<ManageController>(new InjectionConstructor());
container.RegisterFactory<IAuthenticationManager>(o => System.Web.HttpContext.Current.GetOwinContext().Authentication);
Cela répondra à la question posée par le PO et est une réponse à jour pour quiconque le trouve via Google comme moi. RegisterFactory est la nouvelle façon de procéder dans Unity.