2015-01-07 6 views
5

वहाँ इस तरह के रूप में कई नमूने ऑनलाइन Owin/कटाना का उपयोग कर एक डेटाबेस ausername/पासवर्ड संयोजन के आधार पर में उपयोगकर्ताओं को खोजने के लिए और एक का दावा प्रमुख उत्पन्न करने के लिए, कर रहे हैं ...Owin/कटाना UserManager कारखाने व्यवहार कस्टमाइज़

var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); 
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); 
// generate claims here... 

यह ठीक है अगर आप एक नया एप्लीकेशन बना रहे हैं और गंदे काम करने के लिए इकाई फ्रेमवर्क चाहते हैं। लेकिन, मेरे पास आठ साल पुरानी मोनोलिथिक वेबसाइट है जिसे अभी दावे-आधारित प्रमाणीकरण का उपयोग करने के लिए अद्यतन किया गया है। हमारी डेटाबेस हिट मैन्युअल रूप से डीएएल/एसक्यूएल के माध्यम से की जाती है और फिर दावों से उत्पन्न होता है।

कुछ लोग सुझाव दे रहे हैं कि OWIN हमारे मैन्युअल दृष्टिकोण से उपयोग करना आसान है, लेकिन मुझे इसका उपयोग करने वाले लोगों से कुछ इनपुट चाहिए।

क्या यह बदलना संभव है कि UserManager फैक्ट्री उपयोगकर्ताओं को उनके प्रमाण-पत्रों के आधार पर कैसे पाता है? या, क्या कोई और दृष्टिकोण है जिसे मैंने याद किया है? मुझे लगता है कि सभी नमूनों को एंटीटी फ्रेमवर्क डेटाबेस बनाने और खोजों का प्रबंधन करने के लिए बॉयलरप्लेट दृष्टिकोण का उपयोग करना प्रतीत होता है।

+0

हाँ आप अनुकूलित कर सकते हैं कि कैसे UserManager व्यवहार करता है। जिस तरह से इसका डेटा प्राप्त होता है वह 'IUserStore' के कार्यान्वयन के माध्यम से होता है। यहां एक उत्तर दिया गया है जो इसे अनुकूलित करने के तरीके पर आपकी सहायता कर सकता है। http://stackoverflow.com/questions/19940014/asp-net-identity-with-ef-database-first-mvc5/21122865#21122865 – Shoe

उत्तर

12

एएसपी.नेट पहचान थोड़ी अधिक जटिल है, मैं कहूंगा।
अगस्त 2014 में उन्होंने नए संस्करण 2.1 की घोषणा की है और चीजें फिर से बदल गई हैं।
सबसे पहले चलो EntityFramework से छुटकारा पाने:

public class User: IUser<int> 
{ 
    public User() 
    { 
     this.Roles = new List<string>(); 
     this.Claims = new List<UserClaim>(); 
    } 

    public User(string userName) 
     : this() 
    { 
     this.UserName = userName; 
    } 

    public User(int id, string userName): this() 
    { 
     this.Id = Id; 
     this.UserName = userName; 
    } 

    public int Id { get; set; } 
    public string UserName { get; set; } 
    public string PasswordHash { get; set; } 

    public bool LockoutEnabled { get; set; } 
    public DateTime? LockoutEndDateUtc { get; set; } 
    public bool TwoFactorEnabled { get; set; } 

    public IList<string> Roles { get; private set; } 
    public IList<UserClaim> Claims { get; private set; } 
} 

आप कर सकते हैं के रूप में:

Uninstall-Package Microsoft.AspNet.Identity.EntityFramework 

अब हम इंटरफ़ेस को लागू करने User की अपनी परिभाषा IUser (Microsoft.AspNet.Identity) को लागू देखें कि मैंने अपने Id (int) के प्रकार को परिभाषित किया है।

फिर आपको अपने कस्टमर UserManager को Microsoft.AspNet.Identity.UserManager से उत्तराधिकारी को अपने उपयोगकर्ता प्रकार और कुंजी प्रकार को निर्दिष्ट करना होगा।

public class UserManager : UserManager<User, int> 
{ 
    public UserManager(IUserStore<User, int> store): base(store) 
    { 
     this.UserLockoutEnabledByDefault = false; 
     // this.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(10); 
     // this.MaxFailedAccessAttemptsBeforeLockout = 10; 
     this.UserValidator = new UserValidator<User, int>(this) 
     { 
      AllowOnlyAlphanumericUserNames = false, 
      RequireUniqueEmail = false 
     }; 

     // Configure validation logic for passwords 
     this.PasswordValidator = new PasswordValidator 
     { 
      RequiredLength = 4, 
      RequireNonLetterOrDigit = false, 
      RequireDigit = false, 
      RequireLowercase = false, 
      RequireUppercase = false, 
     }; 
    } 
} 

मैंने यहां अपने सत्यापन नियम लागू किए हैं लेकिन यदि आप चाहें तो इसे बाहर रख सकते हैं।

UserManager को UserStore (IUserStore) की आवश्यकता है।

आप यहां अपने डीबी तर्क को परिभाषित करेंगे। लागू करने के लिए कुछ इंटरफेस हैं। हालांकि उनमें से सभी अनिवार्य नहीं हैं।

public class UserStore : 
    IUserStore<User, int>, 
    IUserPasswordStore<User, int>, 
    IUserLockoutStore<User, int>, 
    IUserTwoFactorStore<User, int>, 
    IUserRoleStore<User, int>, 
    IUserClaimStore<User, int> 
{ 

    // You can inject connection string or db session 
    public UserStore() 
    { 
    } 

} 

मैंने प्रत्येक इंटरफ़ेस के लिए सभी विधियों को शामिल नहीं किया है। एक बार जब आप किया है कि आप अपने नए उपयोगकर्ता लिखने के लिए सक्षम हो जाएगा:

public System.Threading.Tasks.Task CreateAsync(User user) 
{ 
} 

आईडी द्वारा यह लाने:

public System.Threading.Tasks.Task<User> FindByIdAsync(int userId) 
{ 
} 

और इतने पर।

फिर आपको Microsoft.AspNet.Identity.Owin.SignInManager से विरासत में अपने SignInManager को परिभाषित करने की आवश्यकता होगी।

public class SignInManager: SignInManager<User, int> 
{ 
    public SignInManager(UserManager userManager, IAuthenticationManager authenticationManager): base(userManager, authenticationManager) 
    { 
    } 

    public override Task SignInAsync(User user, bool isPersistent, bool rememberBrowser) 
    { 
     return base.SignInAsync(user, isPersistent, rememberBrowser); 
    } 
} 

मैं केवल SignInAsync को क्रियान्वित किया है: यह होगा एक ClaimsIdentity उत्पन्न करता है।

यह बहुत अधिक है।

अब आपके Startup कक्षा में आपको OwinUserManager और SignInManager बनाने का तरीका बताएं।

app.CreatePerOwinContext<Custom.Identity.UserManager>(() => new Custom.Identity.UserManager(new Custom.Identity.UserStore())); 
// app.CreatePerOwinContext<Custom.Identity.RoleManager>(() => new Custom.Identity.RoleManager(new Custom.Identity.RoleStore())); 
app.CreatePerOwinContext<Custom.Identity.SignInService>((options, context) => new Custom.Identity.SignInService(context.GetUserManager<Custom.Identity.UserManager>(), context.Authentication)); 

मैं कारखानों आप डिफ़ॉल्ट टेम्पलेट क्योंकि मैं संभव के रूप में सरल रूप में चीजें रखने के लिए करना चाहता था में मिलेगा उपयोग नहीं किया है।

और कुकी का उपयोग करने के लिए आपके आवेदन को सक्षम:

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
     LoginPath = new PathString("/Account/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<Custom.Identity.UserManager, Custom.Identity.User, int>(
     validateInterval: TimeSpan.FromMinutes(30), 
     regenerateIdentityCallback: (manager, user) => 
     { 
     var userIdentity = manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); 
       return (userIdentity); 
    }, 
     getUserIdCallback: (id) => (Int32.Parse(id.GetUserId())) 
     )} 
}); 
अब जबकि आपके खाते नियंत्रक में

- या नियंत्रक लॉगिन करने के लिए जिम्मेदार हैं - आप UserManager और SignInManager प्राप्त करना होगा:

public Custom.Identity.SignInManager SignInManager 
{ 
    get 
    { 
    return HttpContext.GetOwinContext().Get<Custom.Identity.SignInManager>(); 
    } 
} 

public Custom.Identity.UserManager UserManager 
{ 
    get 
    { 
    return HttpContext.GetOwinContext().GetUserManager<Custom.Identity.UserManager>(); 
    } 
} 

आपको लॉगिन के लिए SignInManager का उपयोग करेगा:

var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); 

और UserManager, उपयोगकर्ता बनाने के लिए भूमिकाओं और दावों जोड़ें:

if (ModelState.IsValid) 
{ 
     var user = new Custom.Identity.User() { UserName = model.Email }; 

     var result = await UserManager.CreateAsync(user, model.Password); 
     if (result.Succeeded) 
    { 
     // await UserManager.AddToRoleAsync(user.Id, "Administrators"); 
       // await UserManager.AddClaimAsync(user.Id, new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Country, "England")); 

       await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false); 

     return RedirectToAction("Index", "Home"); 
    } 
     AddErrors(result); 
} 

यह मुश्किल लगता है ... और यह एक तरह से ... है।

यदि आप इसके बारे में अधिक पढ़ना चाहते हैं तो here और here पर एक अच्छा स्पष्टीकरण है।

आप कुछ कोड चलाना चाहते हैं और देखें कि यह कैसे काम करता है, मैं एक साथ कुछ code जो Biggy के साथ काम करता रख दिया है (के रूप में मैं ज्यादा समय ऐसे ही टेबल और सामान को परिभाषित करने के लिए बर्बाद नहीं करना चाहता था) है।

आप GitHub रेपो से मेरे कोड डाउनलोड करने के लिए मौका है, तो आप देखेंगे कि मैं एक माध्यमिक परियोजना (Custom.Identity) जहाँ मैं मेरे सभी ASP.NET पहचान सामान रखा है बनाया है।

केवल nuget संकुल आप की आवश्यकता होगी देखते हैं:

  1. Microsoft.AspNet.Identity.Core
  2. Microsoft.AspNet.Identity.Owin
+0

कमाल का जवाब - बहुत बहुत धन्यवाद। अपेक्षाकृत सरल कुछ के लिए हालांकि बहुत अधिक कोड। यह सब के लिए चालक क्या है? क्या यह ऐप को * जहां * डेटा वास्तव में बैठता है, के बारे में पता नहीं होने देता है। बेहतर अंतःक्रियाशीलता? – EvilDr

+1

आपके साथ सहमत हैं। मैं सोच रहा हूं कि क्या हमें वास्तव में कुछ ऐसा करने के लिए इन सभी चरणों को पार करने की ज़रूरत है जो सीधा होना चाहिए। चालक को सुरक्षा के लिए अपनी टेबल/स्कीमा रखना है।मैं - व्यक्तिगत रूप से - इकाई ढांचे को पसंद नहीं करता हूं और इससे छुटकारा पाना चाहता हूं। विस्तारशीलता शायद। किसी बिंदु पर आप कुछ नोएसक्ल डेटाबेस पर स्विच करने का निर्णय ले सकते हैं। – LeftyX

+1

इकाई फ्रेमवर्क के बारे में सहमत हैं। ब्याज से, आप उपरोक्त कोड से इतना परिचित कैसे हो गए? क्या किसी ने आपको सही दिशा में इंगित किया और आपने इसे अनुभव से उठाया? मुझे लगता है कि मेरे पास एएसपी.नेट के तेजी से बदलावों को बनाए रखने के लिए दिन में पर्याप्त समय नहीं है ... – EvilDr

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