9

Ich füge der ASP.NET MVC 5-Webanwendung ASP.NET Identity-Authentifizierungsfunktionen hinzu.SignInManager-Abhängigkeit injizieren: Funktioniert nicht mit Unity, funktioniert bei Verwendung von OWIN

I Unity über das Projekt für Dependency Injection verwenden, so habe ich beschlossen, Abhängigkeiten von den AccountController im Konstruktor erforderlich zu injizieren:

public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser, string> signInManager) 
{ 
    _userManager = userManager; 
    _signInManager = signInManager; 
} 

Meine Login Methode wie folgt (tatsächlich umgesetzt wird, kopierte ich diesen Code von einer ASP.NET Web Application Projektvorlage mit Individual User Accounts Authentifizierung):

// 
// 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! 
} 

Das Problem ist, dass die Authentifizierung nicht richtig funktioniert - auch wenn ich richtig creden eingegeben Tials und result ist SignInStatus.Success, gibt es keine Authentifizierung Cookies in der Antwort gesendet werden.

Wenn ich jedoch OWIN Infrastruktur verwenden ApplicationSignInManager statt Unity Container zu lösen, funktioniert alles richtig:

// 
// 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, model.Password, model.RememberMe, shouldLockout: true); 
    // Process result and return appropriate view... 
    // Authentication cookies are present in the response! 
} 

Das ist, wie ApplicationSignInManagerStartup Klasse in der Anwendung registriert ist:

app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); 

Und das ist ApplicationSignInManager Deklaration:

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); 
    } 
} 

Hier ist ein Teil meiner Unity-Konfiguration:

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)); 

Die Idee ist, dass die Einheit die gleichen Abhängigkeiten der ApplicationSignInManager Konstruktor als Create Methode führt zur Verfügung stellt. Aber der Ansatz von Unity funktioniert aus irgendeinem Grund nicht: Es werden keine Authentifizierungscookies nach der erfolgreichen Anmeldung gesendet.

Dies ist eine sehr spezifische Frage, aber vielleicht hatte jemand schon einmal ein Problem wie diese? Ich glaube, dieses Verhalten sollte mit OWIN Middleware, Pipeline und wie all diese Sachen beim Start der Anwendung verdrahtet werden.

Antwort

13

Statt IOwinContext im Behälter der Registrierung, nicht IAuthenticationManager registrieren:

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

und haben nur einen Konstruktor für SignInManager:

public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) 

Ich habe die Registrierung mit Unity getan like this, und hier ist the explanation.

+0

Nun, das Problem war in meiner Unity-Konfiguration - ich habe 'ContainerControlledLifetimeManager' anstatt der Standard' TransientLifetimeManager' verwendet. Wie auch immer, dein Artikel hat mir wirklich geholfen, das herauszufinden, also habe ich deine Antwort als akzeptiert markiert. Danke für Ihre Hilfe! –

+1

Awesome verknüpfte Artikel! Ich wünschte, ich hätte sie gefunden, bevor ich den größten Teil des gestrigen Tages verschwendet habe. Danke! –

3

Nur für den Fall, dass Sie auch den RoleManager injizieren müssen, hier ' s wie es mit Unity gemacht wird:

container.RegisterType<IRoleStore<IdentityRole, string>, RoleStore<IdentityRole>>(new InjectionConstructor(typeof(MyDbContext))); 

Vergessen Sie nicht, IAuthenticationManager auch zu registrieren (siehe obige Antwort).

Verwandte Themen