2012-02-22 9 views
5

मेरे पास एक एएसपी एमवीसी 3 आरामदायक सेवा है जो मूल प्रमाणीकरण का उपयोग करती है। स्टैक ओवरफ़्लो खोजने के बाद, मैंने निम्न कोड बनाया।एएसपी एमवीसी 3 एक्शनफिल्टर मूल प्रमाणीकरण के लिए

public class BasicAuthentication : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var req = filterContext.HttpContext.Request; 
     if (String.IsNullOrEmpty(req.Headers["Authorization"])) 
     { 
      filterContext.Result = new HttpNotFoundResult(); 
     } 
     else 
     { 
      var credentials = System.Text.ASCIIEncoding.ASCII 
         .GetString(Convert.FromBase64String(req.Headers["Authorization"].Substring(6))) 
         .Split(':'); 
      var user = new { Name = credentials[0], Password = credentials[1] }; 
      if(!(user.Name == "username" && user.Password == "passwords")) 
      { 
       filterContext.Result = new HttpNotFoundResult(); 
      } 
     } 
    } 
} 

1) क्या कोई एक्शनफ़िल्टर एट्रिब्यूट ऐसा करने का सबसे अच्छा तरीका है?

2) फ़िल्टर कॉन्टेक्स्ट सेटिंग है। नियंत्रक विधि तक पहुंच से इनकार करने का सही तरीका सही है?

3) क्या कुछ भी गलत है?

धन्यवाद।

-Nick

+0

आप बुनियादी (दो चरण प्रमाणीकरण) के साथ प्रपत्र/कस्टम प्रकार प्रमाणन या अभी भी डोमेन खातों का उपयोग करने के लिए बुनियादी उपयोग कर रहे हैं? –

उत्तर

12

1) एक ActionFilterAttribute यह करने के लिए सबसे अच्छा तरीका है?
मुझे ऐसा लगता है। यह दृष्टिकोण Authorize विशेषता में निर्मित कार्यान्वयन को प्रतिबिंबित करता है।

2) filterContext.Result सेटिंग नियंत्रक विधि तक पहुंच से इनकार करने का सही तरीका है?
हां। यह है कि इसके लिए क्या है। (1)

3) क्या कुछ भी गलत है?

  • आप को लगता है कि प्राधिकरण हैडर की सामग्री सही स्वरूप में है और सही ढंग से एन्कोड किया गया है।
  • आप मानते हैं कि अनुरोध मूल स्वायत्तता के लिए है और अन्य प्रमाणीकरण योजना नहीं है।
  • HttpNotFoundResult() के माध्यम से http 404 त्रुटि के बजाय http 401 त्रुटि भेजने के लिए मैं HttpUnauthorizedResult() का उपयोग करना पसंद करूंगा।

आपके कोड के कार्यान्वयन में नीचे (जो मुझे यकीन है कि इसके मुद्दे भी हैं)।

public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     try 
     { 
      if (String.IsNullOrEmpty(filterContext.HttpContext.Request.Headers["Authorization"])) 
      { 
       filterContext.Result = new HttpUnauthorizedResult(); 
      } 
      else 
      { 
       if (filterContext.HttpContext.Request.Headers["Authorization"].StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase)) 
       { 
        string[] credentials = ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(filterContext.HttpContext.Request.Headers["Authorization"].Substring(6))).Split(':'); 

        if (credentials.Length == 2) 
        { 
         if (String.IsNullOrEmpty(credentials[0])) 
         { 
          filterContext.Result = new HttpUnauthorizedResult(); 
         } 
         else if (!(credentials[0] == "username" && credentials[1] == "passwords")) 
         { 
          filterContext.Result = new HttpUnauthorizedResult(); 
         } 
        } 
        else 
        { 
         filterContext.Result = new HttpUnauthorizedResult(); 
        } 
       } 
       else 
       { 
        filterContext.Result = new HttpUnauthorizedResult(); 
       } 
      } 

      base.OnActionExecuting(filterContext); 
     } 
     catch 
     { 
      filterContext.Result = new HttpUnauthorizedResult(); 
     } 
    } 

नोट्स

  • मैं उपयोगकर्ता नाम और पासवर्ड के लिए अवैध चरित्र चेकों शामिल नहीं किया है।
  • मैं अपवाद हैंडलिंग को कार्यान्वित करने के तरीके पर बस नहीं जा सका इसलिए मैं सादगी के साथ चला गया हूं।

संदर्भ

(1) http://msdn.microsoft.com/en-us/magazine/gg232768.aspx

-2

1) नहीं है, ActionFilter गुण एक उपयोगकर्ता को प्रमाणित करने के लिए एक अच्छा तरीका नहीं है। (हम एक बार प्रमाणित करने के लिए की जरूरत है और कुकी को प्रमाणित निर्धारित करते हैं, तो HttpContext.User तक कुकी का समाप्ति समय प्रमाणीकृत रहेंगे जब तक)

2) हाँ, filtercontext.Result की स्थापना एक आदर्श उपयोग रोकने के लिए रास्ता है। (लेकिन HttpNotFoundResult बताए करने के बजाय, RedirectResult का उपयोग प्रवेश पृष्ठ पर रीडायरेक्ट करने के लिए)

3) मैं वास्तव में समझ में नहीं आता क्यों प्राधिकरण के लिए इस तरह के कार्यान्वयन के लिए करते हैं। सबसे अच्छा तरीका एक ऐसा कार्य होना होगा जो फॉर्म पोस्ट डेटा (उपयोगकर्ता नाम और पासवर्ड) प्राप्त करेगा। और अनधिकृत पहुंच को रोकने के लिए प्राधिकृत विशेषता का उपयोग करें।

निम्नलिखित VS2010 में डिफ़ॉल्ट MVC3 नमूना अनुप्रयोग से कोड है।

[HttpPost] 
    public ActionResult LogOn(LogOnModel model, string returnUrl) 
    { 
     if (ModelState.IsValid) 
     { 
      if (Membership.ValidateUser(model.UserName, model.Password)) 
      { 
       FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); 
       if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") 
        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) 
       { 
        return Redirect(returnUrl); 
       } 
       else 
       { 
        return RedirectToAction("Index", "Home"); 
       } 
      } 
      else 
      { 
       ModelState.AddModelError("", "The user name or password provided is incorrect."); 
      } 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 
+0

मैं फॉर्म लॉगिन मॉडल को समझता हूं, और इसे सामान्य वेबसाइट के लिए उपयोग करता हूं। यह एक आरामदायक सेवा के लिए कैसे काम करता है? उपयोगकर्ता लॉगिन कैसे प्रदान करता है? – Nikhil

+0

एमवीसी फॉर्म प्रमाणीकरण का उपयोग कर अभी भी आराम से है। क्या आप कुछ सिस्टम/सेवा की तलाश कर रहे हैं, एमवीसी यूरी को नेटवर्क क्रेडेंशियल्स पास करने का आह्वान करेंगे। यदि ऐसा है, तो उपर्युक्त दृष्टिकोण ठीक लगता है। (लेकिन बेहतर है कि आप बेसकंट्रोलर कर सकते हैं और इससे सभी बाल नियंत्रकों का उत्तराधिकारी हो सकते हैं। फिर आप उपर्युक्त निष्पादन विधि में उपरोक्त कोड लिख सकते हैं, ** जब तक आप सभी को एपीआई द्वारा कोड नहीं लगाया जाता है **) – Manas

+2

मुझे लगता है कि आपने उत्तर देने के दौरान प्रश्न शीर्षक में "सेवा" और "मूल प्रमाणीकरण" शब्द को अनदेखा कर लिया है। – humblelistener

8

के पुनर्स्थापन संस्करण एड्रियन

public class BasicAuthenticationAttribute : ActionFilterAttribute 
{ 
    private static readonly string AuthorizationHeader = "Authorization"; 
    private static readonly string BasicHeader = "Basic "; 
    private static readonly string Username = "username"; 
    private static readonly string Password = "password"; 
    private static readonly char[] Separator = ":".ToCharArray(); 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     try 
     { 
      if (!Authenticated(filterContext.HttpContext.Request)) 
       filterContext.Result = new HttpUnauthorizedResult(); 

      base.OnActionExecuting(filterContext); 
     } 
     catch 
     { 
      filterContext.Result = new HttpUnauthorizedResult(); 
     } 
    } 

    private bool Authenticated(HttpRequestBase httpRequestBase) 
    { 
     bool authenticated = false; 

     if (String.IsNullOrEmpty(httpRequestBase.Headers[AuthorizationHeader]) == false && 
      httpRequestBase.Headers[AuthorizationHeader].StartsWith(BasicHeader, StringComparison.InvariantCultureIgnoreCase)) 
     { 
      string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(
       httpRequestBase.Headers[AuthorizationHeader].Substring(BasicHeader.Length))).Split(Separator); 

      if (credentials.Length == 2 && credentials[0] == Username && credentials[1] == Password) 
      { 
       authenticated = true; 
      } 
     } 

     return authenticated; 
    } 
} 
+1

+1। बहुत उपयोगी। हालांकि पहली शर्त अगर "प्रमाणित" नहीं होनी चाहिए तो HttpUnauthorisedResult को बढ़ाएं। – fluent

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