我正在使用ASP.NET MVC 5、EF6、ASP.NET Identity和users,我希望在构建网站时使用身份框架提供的功能来对用户进行操作和注册。
Startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(DbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
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<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
}
}IdentityConfig.cs
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
await configSendGridasync(message);
}
private async Task configSendGridasync(IdentityMessage message)
{
var myMessage = new SendGridMessage();
myMessage.AddTo(message.Destination);
myMessage.From = new System.Net.Mail.MailAddress("John@Smith.ko", "JOhn Smith");
myMessage.Subject = message.Subject;
myMessage.Text = message.Body;
myMessage.Html = message.Body;
var creds = new NetworkCredential("user", "pass");
var transport = new Web(creds);
if (transport != null)
{
await transport.DeliverAsync(myMessage);
}
else
{
Trace.TraceError("Failed to create Web transport.");
await Task.FromResult(0);
}
}
}
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
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<DbContext>()));
// 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 = false,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = false,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
manager.EmailService = new EmailService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
// Configure the application sign-in manager which is used in this application.
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);
}
}
public class ApplicationRoleManager : RoleManager<IdentityRole>
{
public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore)
: base(roleStore)
{
}
public static ApplicationRoleManager Create(
IdentityFactoryOptions<ApplicationRoleManager> options,
IOwinContext context)
{
var manager = new ApplicationRoleManager(
new RoleStore<IdentityRole>(
context.Get<DbContext>()));
return manager;
}
}UnityConfig.cs
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion
public static void RegisterTypes(IUnityContainer container)
{
#region AutoMapper DI
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<AutoMapperWebProfileConfiguration>();
});
var mapper = config.CreateMapper();
container.RegisterInstance(config.CreateMapper());
#endregion
#region userManager and roleManager DI
var accountInjectionConstructor = new InjectionConstructor(new DbContext());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(accountInjectionConstructor);
container.RegisterType<IRoleStore<IdentityRole, string>,
RoleStore<IdentityRole, string, IdentityUserRole>>(accountInjectionConstructor);
#endregion
#region AuthenticationManager
container.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication));
#endregion
#region IdentityConfig injects
container.RegisterType<DbContext>();
container.RegisterType<ApplicationSignInManager>();
container.RegisterType<ApplicationUserManager>();
container.RegisterType<EmailService>();
container.RegisterType<IMappingEngine>(new InjectionFactory(_ => Mapper.Engine));
#endregion
}
}AuthController.cs
public class AuthController : Controller
{
private IMapper mapper;
private RoleManager<IdentityRole> roleManager;
private IAuthenticationManager authManager;
private ApplicationUserManager userManager;
private ApplicationSignInManager signInManager;
public AuthController(IMapper mapper, IRoleStore<IdentityRole, string> roleStore, IAuthenticationManager authManager, ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
this.mapper = mapper;
this.roleManager = new RoleManager<IdentityRole>(roleStore);
this.authManager = authManager;
this.userManager = userManager;
this.signInManager = signInManager;
} //rest omitted for brevity.问题
当我运行代码时,Startup.cs中的所有内容都会被执行,所有对象都会从IdentityConfig.cs中实例化,因此我得到了一个具有所有所需属性集(email服务、userTokenprovider等)的UserManager实例,但是当到达控制器时,会注入另一个没有设置这些属性的对象,因此我得到了许多异常(例如,未注册的IUserTokenProvider等等)。我假设注入到Controller中的UserManager是由Unity注入的,而不是由Startup.cs创建的。与控制器中定义的rest私有属性的故事相同。我如何告诉Unity使用Startup.cs创建的对象?
发布于 2016-03-11 08:27:18
很明显,OWIN和Unity正在您的代码中创建自己的标识对象,因此取决于使用,您将收到不同的对象。为了避免这一点,你必须决定哪一个人负责创建你的对象,拥有还是统一。由于建议让DI做这样的事情,所以最好像这样更改启动文件:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationUserManager>());
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationSignInManager>());
// other configs
}现在OWIN从Unity获得了相同的对象。但是,您还需要一些额外的配置和考虑,以整合统一和身份。I've already answered this看过了。
https://stackoverflow.com/questions/35912600
复制相似问题