2009-09-17 8 views
58

मेरे पास एक उपयोगकर्ता तालिका के साथ एक मौजूदा डेटाबेस है, और हम डेटाबेस लेने और एएसपी.नेट एमवीसी में निर्मित एक नई प्रणाली के लिए इसका उपयोग करने की योजना बना रहे हैं। हालांकि, मुझे इस बारे में अनिश्चितता है कि मैं एक लॉगिन सिस्टम बनाने में सक्षम हूं या नहीं, जो अंतर्निहित खाता नियंत्रक या नियमित सदस्यता प्रदाता का उपयोग नहीं करता है ताकि हम अभी भी मौजूदा तालिका संरचना का उपयोग कर सकें।क्या एएसपी.नेट एमवीसी के साथ लॉगऑन सिस्टम बनाना संभव है लेकिन सदस्यता प्रदाता का उपयोग नहीं करना है?

तो मेरा सवाल है, क्या यह संभव होगा? या यह भी करना मुश्किल है अगर यह है?

चीजों को करने और सबसे सरल करने का सबसे व्यापक रूप से स्वीकार्य तरीका क्या है?

उत्तर

81

मेरे पास यह वही आवश्यकता थी। मेरे पास मेरा अपना उपयोगकर्ता और भूमिका स्कीमा था और एएसपीनेट सदस्यता स्कीमा में माइग्रेट नहीं करना चाहता था, लेकिन मैं प्राधिकरण और भूमिकाओं की जांच के लिए एएसपी.नेट एमवीसी एक्शन फ़िल्टर का उपयोग करना चाहता था। मुझे वास्तव में क्या करने की आवश्यकता है, यह जानने के लिए खुदाई की उचित मात्रा में करना था, लेकिन अंत में यह अपेक्षाकृत आसान था। मैं आपको परेशानी बचाऊंगा और आपको बताऊंगा कि मैंने क्या किया।

1) मैंने System.Web.Security.MembershipProvider से प्राप्त एक क्लास बनाई है। सदस्यता प्रदाता के प्रमाणीकरण से संबंधित कार्यों के सभी प्रकार के लिए सार तत्वों का एक टन है जैसे पासवर्ड भूलना, पासवर्ड बदलना, नया उपयोगकर्ता बनाना आदि। मैं चाहता था कि मैं अपनी खुद की स्कीमा के खिलाफ प्रमाणित करने की क्षमता रखूं। तो मेरी कक्षा मुख्य रूप से खाली ओवरराइड निहित है। मैं सिर्फ overrode ValidateUser:

public override bool ValidateUser(string username, string password) 
{ 
    if (string.IsNullOrWhiteSpace(username) || 
     string.IsNullOrWhiteSpace(password)) 
     return false; 

    string hash = EncryptPassword(password); 
    User user = _repository.GetByUserName(username); 
    if (user == null) return false; 

    return user.Password == hash; 
} 

2) मैं एक वर्ग कि System.Web.Security.RoleProvider से ली गई बनाया। दोबारा, मेरे पास सिर्फ उन सभी फ्लफ के लिए खाली कार्यान्वयन था जिन्हें मुझे भूमिका बनाने और बदलने की आवश्यकता नहीं थी।

public override string[] GetRolesForUser(string username) 
{ 
    User user = _repository.GetByUserName(username); 
    string[] roles = new string[user.Role.Rights.Count + 1]; 
    roles[0] = user.Role.Description; 
    int idx = 0; 
    foreach (Right right in user.Role.Rights) 
     roles[++idx] = right.Description; 
    return roles; 
} 

public override bool IsUserInRole(string username, string roleName) 
{ 
    User user = _repository.GetByUserName(username); 
    if(user!=null) 
     return user.IsInRole(roleName); 
    else 
     return false; 
} 

3) तब मैं अपने web.config में इन दो वर्गों खामियों को दूर:

<membership defaultProvider="FirstlookMemberProvider" userIsOnlineTimeWindow="15"> 
    <providers> 
    <clear/> 
    <add name="FirstlookMemberProvider" type="FirstlookAdmin.DomainEntities.FirstlookMemberProvider, FirstlookAdmin" /> 
    </providers> 
</membership> 
<roleManager defaultProvider="FirstlookRoleProvider" enabled="true" cacheRolesInCookie="true"> 
    <providers> 
    <clear/> 
    <add name="FirstlookRoleProvider" type="FirstlookAdmin.DomainEntities.FirstlookRoleProvider, FirstlookAdmin" /> 
    </providers> 
</roleManager> 

यह है कि मैं सिर्फ दो तरीकों overrode। डिफ़ॉल्ट प्राधिकरण कार्रवाई फ़िल्टर इन कक्षाओं का उपयोग करेंगे। आपको अभी भी लॉगिन पेज साइन इन करना होगा और साइन आउट करना होगा। इसके लिए सामान्य रूप से मानक रूप प्रमाणीकरण कक्षाओं का उपयोग करें जैसे आप सामान्य रूप से करेंगे।

+1

+1 के साथ प्राप्त करते हैं। प्रदाता को अनुकूलित करना इसे करने का एक सही तरीका है। यह इंगित करने के लिए धन्यवाद कि यह भी बहुत काम नहीं है। –

+4

ओह, यह इंगित करने के लायक है कि पासवर्ड को वास्तव में हैशिंग से पहले एक नॉन के साथ नमकीन किया जाना चाहिए। –

+0

मुझे इसे पुनर्जीवित करने और आपको परेशान करने के लिए खेद है, लेकिन क्या आपके समाधान पर कुछ और जानकारी प्राप्त करना संभव है? मैं थोड़ा उलझन में हूं कि आपने भूमिका प्रबंधन कैसे किया। – Ciel

10

बेशक आप कर सकते हैं। मैंने अपनी परियोजनाओं के लिए सदस्यता प्रदाता को पूरी तरह अनदेखा कर दिया।

आपको अपना स्वयं का एक्शनफ़िल्टर लागू करने की आवश्यकता है। असल में, नियंत्रक कार्रवाई हिट होने से पहले यह नियंत्रण को रोक देगा। इसके अंदर आप तय करते हैं कि कार्रवाई जारी रखना है या उपयोगकर्ता को लॉगिन पृष्ठ पर रीडायरेक्ट करना है या नहीं।

विशेषता के लिए आप अपने प्रमाणीकरण/प्राधिकरण मॉडल का समर्थन करने के लिए आवश्यक किसी भी पैरामीटर को परिभाषित कर सकते हैं।

public class AuthorizationAttribute : ActionFilterAttribute, IActionFilter 
{ 
    public MyRole UserRole { get; set; } 

    void IActionFilter.OnActionExecuting (ActionExecutedContext filterContext) 
    { 
     // Decide whether to grant access to the action or redirect away 
    } 
} 

[Authorization (UserRole = MyRole.All)] 
public class UserController : Controller 
{ 
    [Authorization (UserRole = MyRole.Admin)] 
    public ActionResult Delete() 
    { 
    } 
} 

चिंताओं टिप्पणी में व्यक्त के बारे में। हां, आउटपुट कैश को सक्षम करने से प्राधिकरण में हस्तक्षेप होगा। सिर्फ एक को इसके बारे में पता होना चाहिए। समस्या का

स्पष्टीकरण: ASP.NET MVC Tip #40 - Don’t Cache Pages that Require Authorization

+0

क्या आप कस्टम बना सकते हैं? बेशक व्यवसाय अलग-अलग होते हैं, इसलिए आप केवल 'Role.Admin' की बजाय' Role.IsAccountsAdmin' चाहते हैं। – Kezzer

+0

ये कस्टम हैं, बस नाम मेल खाते हैं। अस्पष्टता को दूर करने के लिए उन्हें एक पल में अपडेट कर देगा। –

+0

क्या यह बस पूर्व-जेनरेट की गई खाता नियंत्रक फ़ाइल में जाएगा या क्या मुझे अपना खुद का निर्माण करने की आवश्यकता होगी? – LiamGu

1

आपके पास कम से कम दो संभावनाओं

  • एक कस्टम क्रिया फिल्टर विशेषता है कि आपके प्राधिकरण की जांच प्रदान करेगा
  • एक कस्टम IHttpModule कि भर जाएगा सब लॉग इन उपयोगकर्ता (भूमिकाओं सहित) के लिए आवश्यक डेटा और आप मौजूदा एक्शन फ़िल्टर
का उपयोग कर सकते हैं

दूसरी पसंद नियमित वेब रूपों के साथ भी उपयोग की जा सकती है।

11

जब भी कोई आपको बताता है कि कुछ सुरक्षा-संबंधित "आसान" है, तो वे लगभग हमेशा गलत होते हैं। सुरक्षा में बहुत सारी सूक्ष्मताएं हैं जो गैर विशेषज्ञों को याद आती है।

विशेष रूप से, प्रमाणीकरण का कोई भी रूप जो कैशिंग के साथ स्पष्ट रूप से सौदा नहीं करता है, मूल रूप से टूटा हुआ है। जब कोई कार्रवाई परिणाम कैश किया जाता है, तो यह एएसपी.नेट के भीतर होता है, जरूरी नहीं कि एएसपी.नेट एमवीसी स्टैक के भीतर। यदि आप AuthorizeAttribute के स्रोत स्रोत की जांच करते हैं, तो आप देखेंगे कि इसमें कुछ मुश्किल मुश्किल लेकिन प्रभावी कोड शामिल है ताकि यह सुनिश्चित किया जा सके कि यह हमेशा चलता है, भले ही कार्रवाई परिणाम कैश किया जाता है।

The best way, by far, to customize ASP.NET MVC authentication is to write a custom ASP.NET membership provider. मैं दावा नहीं करता कि यह मूर्खतापूर्ण है, लेकिन इस मार्ग में टूटी हुई सुरक्षा कार्यान्वयन के साथ अन्य तरीकों के साथ परेशानी पाने के कम तरीके हैं। इस तकनीक का एक बड़ा फायदा यह है कि आप लगभग किसी भी समय एक अलग प्राधिकरण प्रणाली को प्रतिस्थापित कर सकते हैं, बिना कोड परिवर्तन के।

यदि आपको एक कस्टम एमवीसी विशेषता लागू करना है, तो आपको थ्रेड सुरक्षा के संबंध में स्रोत कोड में टिप्पणियों की सावधानीपूर्वक ध्यान रखना, AuthorizeAttribute को उपप्रकार करना चाहिए और AuthorizeCore को ओवरराइड करना चाहिए।

+0

वर्तमान में, मेरे पास चीजों को करने का "सेट" तरीका नहीं है, मुझे पता है कि मुझे मौजूदा डेटा और टेबल संरचना का उपयोग करना है, इसलिए इसे करने का सबसे आसान, सरल और सबसे सुरक्षित तरीका आदर्श है कि मैं ' एम के बाद क्या यह कस्टम सदस्यता प्रदाता लिखना विशेष रूप से आसान है? मैंने पहले और पहली नज़र में ऐसा नहीं किया है, ऐसा लगता है कि वास्तव में ऐसा करना थोड़ा मुश्किल है? – LiamGu

+1

यहां एक वीडियो http://www.asp.net/learn/videos/video-189.aspx और एक लेख http://www.devx.com/asp/Article/29256 है, इसे कैसे करें। यह काम है, लेकिन कड़ी मेहनत नहीं है। यदि ऐसा करने के लिए बहुत अधिक काम लगता है, ठीक है, जैसा कि मैंने कहा, अन्य समाधान केवल "आसान" लग सकते हैं क्योंकि वे अनिवार्य रूप से टूटे हुए हैं, सुरक्षा, सुविधाओं और मॉड्यूलरिटी में भारी अंतर के साथ। –

+1

मैं ऐसे तरीके का उपयोग करता हूं जो व्यक्तिगत रूप से टूटा नहीं जाता है, खासकर जब यह ऐप बाहरी रूप से भी सुलभ होगा। मुझे जाना होगा और देखें कि क्या होता है। – LiamGu

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