9

का उपयोग कर रहा ASP.NET MVC 5 वेब आवेदन करने के लिए ASP.NET पहचान प्रमाणीकरण कार्यक्षमता जोड़ने हूँ काम करता है।इंजेक्शन SignInManager निर्भरता: एकता के साथ काम नहीं करता है, जब Owin

मैं परियोजना भर में निर्भरता इंजेक्शन के लिए एकता का उपयोग कर रहा है, इसलिए मैं निर्माता में AccountController के लिए आवश्यक निर्भरता इंजेक्षन करने का फैसला किया:

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

मेरे Login पद्धति का अनुसरण (वास्तव में के रूप में कार्यान्वित किया जाता है, मुझे लगता है कि कोड की नकल की Individual User Accounts प्रमाणीकरण के साथ एक ASP.NET Web Application प्रोजेक्ट टेम्पलेट) से:

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

समस्या यह है कि प्रमाणीकरण सही ढंग से काम नहीं करता है - भले ही मैं सही creden में प्रवेश किया tials और resultSignInStatus.Success है, प्रतिक्रिया में कोई प्रमाणीकरण कुकीज़ नहीं भेजी जा रही है।

हालांकि, अगर मैं एकता कंटेनर के बजाय ApplicationSignInManager हल करने OWIN बुनियादी ढांचे का उपयोग करें, सब कुछ सही ढंग से काम करता है:

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

है कि कैसे ApplicationSignInManager आवेदन में पंजीकृत है Startup वर्ग:

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

यहाँ मेरी एकता विन्यास का एक हिस्सा है:

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

विचार यह है कि एकता ApplicationSignInManager निर्माता के रूप में Create विधि करता है के लिए एक ही निर्भरता प्रदान करता है। लेकिन एकता का दृष्टिकोण किसी कारण से काम नहीं करता है: कोई प्रमाणीकरण कुकी में सफल लॉग के बाद भेजा जा रहा

यह बहुत विशिष्ट सवाल है, लेकिन शायद किसी को इस से पहले की तरह एक समस्या का सामना करना पड़ा।? मेरा मानना ​​है कि यह व्यवहार ओविन मिडलवेयर, पाइपलाइन से संबंधित होना चाहिए और एप्लिकेशन स्टार्टअप पर उन सभी चीजों को कैसे तारित किया जा रहा है। कंटेनर में IOwinContext पंजीकरण की

उत्तर

13

इसके बजाय, रजिस्टर करते IAuthenticationManager:

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

और SignInManager के लिए केवल एक निर्माता है:

public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) 

मैं एकता like this के साथ पंजीकरण किया है, और यहाँ है the explanation.

+0

ठीक है, समस्या मेरी एकता विन्यास में था - मैं 'ContainerControlledLifetimeManager' डिफ़ॉल्ट' TransientLifetimeManager' के बजाय इस्तेमाल किया। वैसे भी, आपके आलेख ने वास्तव में इसे समझने में मेरी सहायता की, इसलिए मैंने आपके उत्तर को स्वीकार किए जाने के रूप में चिह्नित किया। आपकी सहायताके लिए धन्यवाद! –

+1

बहुत बढ़िया जुड़े लेख! इच्छा है कि कल मैं सबसे ज्यादा बर्बाद होने से पहले उन्हें पाउंगा। Thanx! –

3

बस मामले में आप के रूप में अच्छी RoleManager सुई, यहाँ की जरूरत है ' यह एकता के साथ कैसे किया जाता है:

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

IAuthenticationManager को भी पंजीकृत करने के लिए मत भूलना (ऊपर जवाब देखें)।

संबंधित मुद्दे