我将ASP.NET身份认证功能添加到ASP.NET MVC 5 Web应用程序.
我在整个项目中使用Unity进行依赖注入,所以我决定在构造函数中注入AccountController所需的依赖项:
public AccountController(UserManager<ApplicationUser> userManager,SignInManager<ApplicationUser,string> signInManager) { _userManager = userManager; _signInManager = signInManager; }
我的登录方法实现如下(实际上,我将ASP.NET Web应用程序项目模板中的代码复制到个人用户帐户身份验证):
// // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(Loginviewmodel model,string returnUrl) { var result = await _signInManager.PasswordSignInAsync(model.Email,model.Password,model.RememberMe,shouldLockout: true); // Process result and return appropriate view... // However,there are no authentication cookies in the response! }
问题是身份验证不正确 – 即使输入正确的凭据,结果是SignInStatus.Success,在响应中也没有发送身份验证cookie.
但是,如果我使用OWIN基础结构来解决ApplicationSignInManager而不是Unity容器,则一切正常:
// // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(Loginviewmodel model,string returnUrl) { var owinSignInManager = HttpContext.GetowinContext().Get<ApplicationSignInManager>(); var result = await owinSignInManager.PasswordSignInAsync(model.Email,shouldLockout: true); // Process result and return appropriate view... // Authentication cookies are present in the response! }
ApplicationSignInManager在应用程序启动类中注册的方式如下:
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
这是ApplicationSignInManager声明:
public class ApplicationSignInManager : SignInManager<ApplicationUser,string> { public ApplicationSignInManager(ApplicationUserManager userManager,IAuthenticationManager authenticationManager) : base(userManager,authenticationManager) { } public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options,IOwinContext context) { var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(new DatabaseContext())); return new ApplicationSignInManager(userManager,context.Authentication); } }
这是Unity配置的一部分:
unityContainer.RegisterType<HttpContextBase>(new InjectionFactory(c => new HttpContextwrapper(HttpContext.Current))); unityContainer.RegisterType<IOwinContext>(new InjectionFactory(c => c.Resolve<HttpContextBase>().GetowinContext())); unityContainer.RegisterType<IAuthenticationManager>(new InjectionFactory(c => c.Resolve<IOwinContext>().Authentication));
这个想法是,Unity提供与Create方法相同的依赖关系到ApplicationSignInManager构造函数.但是Unity的方法由于某种原因不起作用:成功登录后不会发送身份验证cookie.
这是非常具体的问题,但也许有人面对这样的问题?我相信这个行为应该与OWIN中间件,管道以及应用程序启动时所有的东西如何联系在一起.
而不是在容器中注册IOwinContext,请注册IAuthenticationManager:
container.RegisterType<IAuthenticationManager>( new InjectionFactory(c => HttpContext.Current.GetowinContext().Authentication));
public ApplicationSignInManager(ApplicationUserManager userManager,IAuthenticationManager authenticationManager)
我已经完成了Unity like this的注册,这里是the explanation.