11

मैं एएसपी.नेट एमवीसी 5 प्रोजेक्ट पर काम कर रहा हूं जिसमें फॉर्म प्रमाणीकरण सक्षम है। परियोजना वर्तमान में परीक्षण चरण में है, और Azure पर ऑनलाइन होस्ट की गई है, लेकिन प्रोजेक्ट स्वामी साइट पर सभी सार्वजनिक पहुंच को अक्षम करना चाहता है (क्योंकि साइट के कुछ हिस्सों में उपयोगकर्ता को प्रमाणित करने की आवश्यकता नहीं है)।एएसपी.नेट एमवीसी 5 बेसिक HTTP प्रमाणीकरण और एंटीफोर्गेरी टोकन अपवाद

इस परीक्षण चरण के लिए, हमने इस link से मूल HTTP प्रमाणीकरण को लागू करने का निर्णय लिया है। मैं कोड बदल दिया है, तो यह बेहतर सूट मेरी जरूरतों:

public class BasicAuthenticationAttribute : FilterAttribute, IAuthorizationFilter 
{ 
    public string BasicRealm { get; set; } 

    protected string Username { get; set; } 
    protected string Password { get; set; } 

    public BasicAuthenticationAttribute(string username, string password) 
    { 
     this.Username = username; 
     this.Password = password; 
    } 

    public void OnAuthorization (AuthorizationContext filterContext) 
    { 
     var req = filterContext.HttpContext.Request; 
     var auth = req.Headers["Authorization"]; 
     if (!String.IsNullOrEmpty(auth)) 
     { 
      var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':'); 
      var user = new { Name = cred[0], Pass = cred[1] }; 

      if (user.Name == Username && user.Pass == Password) 
       return; 
     } 

     var res = filterContext.HttpContext.Response; 
     var alreadySent = HttpContext.Current.Items.Contains("headers-sent"); 

     if (!alreadySent) 
     { 
      res = filterContext.HttpContext.Response; 
      res.StatusCode = 401; 
      res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test")); 

     } 
    } 
} 

मैं भी एक वैश्विक फिल्टर के रूप में यह पंजीकृत कर लिया है: जब मैं प्रोजेक्ट को चलाने

public class FilterConfig 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorExtendedAttribute()); 
     filters.Add(new BasicAuthenticationAttribute(AppConfig.BasicUsername, AppConfig.BasicPassword)); 
    } 
} 

हालांकि, कुछ मुद्दे हैं । यदि मैं कोड के इस संस्करण का उपयोग करता हूं:

 if (!alreadySent) 
     { 
      res = filterContext.HttpContext.Response; 
      res.StatusCode = 401; 
      res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test")); 
     } 

सफल लॉगिन के बाद यह लगातार लॉगिन पृष्ठ पर रीडायरेक्ट करता है।

लेकिन अगर मैं

res.End(); 

res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test")); 

Antiforgerytoken के बाद cshtml फाइलों में संलग्न फेंकता System.Web.HttpException

सर्वर हेडर संलग्न नहीं कर सकते हैं के बाद HTTP हेडर किया गया है भेज दिया।

लेकिन इस मामले में, यह अंततः सफलतापूर्वक प्रमाणित करता है।

मैं वर्तमान में इस पर फंस गया हूं, और इस समस्या को हल करने के बारे में कोई जानकारी नहीं है, क्योंकि फ़ॉर्म प्रमाणीकरण बंद करना और विकल्प नहीं है, और मैं सभी एंटीफोर्गेरी टोकन और उनकी सत्यापन को हटा नहीं सकता।

+2

क्यों आप इस दृष्टिकोण चुना?यदि आप एक कस्टम 'प्रमाणीकरण फ़िल्टर' बनाना चाहते हैं, तो आपको 'प्राधिकरण एट्रिब्यूट' से उत्तराधिकारी होना चाहिए, 'अनधिकृत' फ़ंक्शन को ओवरराइड करना, अनधिकृत अनुरोधों के लिए 'झूठी' वापसी करना और उन्हें 'हैंडलयूनार्डराइज्ड रिक्वेस्ट' फ़ंक्शन में संभालना चाहिए। – AnhTriet

+0

यदि आप Res.StatusCode लाइन res.AppendHeader लाइन के साथ फ़्लिप करते हैं तो क्या होगा? क्या स्टेटसकोड मान "बॉडी" के हिस्से के रूप में गिना जाता है ताकि हेडर को किसी और से लिखे जाने से बंद कर दिया जाए? कृपया नीचे एंड्रयू की प्रतिक्रिया पर विचार करें। –

+0

कृपया मूल ऑथ का उपयोग न करें। ध्यान दें कि आपके द्वारा संदर्भित अन्य प्रश्न 6 साल की तरह है, और फिर भी बेहतर विकल्प थे। देखें: http://adrianotto.com/2013/02/why-http-basic-auth-is-bad/ – nothingisnecessary

उत्तर

1

क्या आपने res.AppendHeader (..) से पहले इस पंक्ति को आजमाया है?

Response.ClearHeaders(); 
3

मैं तुम्हें ASP.NET पहचान सदस्यता प्रदाता का उपयोग करने के बाद से यह MVC 5 में शामिल किया गया है इस आप बस कोड का एक बहुत कुछ लिखे बिना उपयोगकर्ताओं को प्रमाणित कर सकते हैं के रूप में यह पिछले सदस्यता के साथ था का उपयोग करते हुए सुझाव है। यह आंतरिक कुकीज़ के साथ बाहरी लॉगिन का भी उपयोग कर सकता है जैसे कि आप फॉर्म प्रमाणीकरण विधि का उपयोग करते हैं। आपको जो कुछ चाहिए वह कोड में सरल विन्यास बनाना है और आपको अपने कस्टम फ़िल्टर लिखने की आवश्यकता नहीं है।

1

req.End() के साथ अनुरोध समाप्त करने के बजाय, मुझे लगता है कि आप नीचे दिखाए गए अनुसार filterContext.Result सेट करना चाहते हैं। नॉन-नल वैल्यू के परिणाम को सेट करने से बाकी एमवीसी पाइपलाइन की प्रसंस्करण में बाधा आती है और प्रतिक्रिया को ब्राउज़र पर भेजा जा सकता है, लेकिन इसे End() के रूप में प्रतिक्रिया को सील नहीं करना चाहिए, इसलिए आपको अपवाद नहीं मिलना चाहिए हेडर पहले ही भेजे जा रहे हैं।

इस प्रयास करें:

filterContext.Result = new HttpUnauthorizedResult(); 
संबंधित मुद्दे