asp.net mvc प्रमाणीकरण और प्रमाणीकरण विफलताओं के लिए AuthorizeAttribute लॉगिन पृष्ठ पर रीडायरेक्ट क्यों करता है?




asp.net-mvc authentication (5)

एएसपी.नेट एमवीसी में, आप AuthorizeAttribute साथ एक नियंत्रक विधि को चिह्नित कर सकते हैं, जैसे:

[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
    // ...
}

इसका अर्थ यह है कि, यदि वर्तमान में लॉग-इन उपयोगकर्ता "CanDeleteTags" भूमिका में नहीं है, तो नियंत्रक विधि कभी नहीं कहा जाएगा।

दुर्भाग्यवश, असफलताओं के लिए, AuthorizeAttribute HttpUnauthorizedResult देता है, जो हमेशा HTTP स्थिति कोड 401 देता है। इससे लॉगिन पृष्ठ पर पुनर्निर्देशन होता है।

यदि उपयोगकर्ता लॉग इन नहीं है, तो यह सही समझ में आता है। हालांकि, यदि उपयोगकर्ता पहले से लॉग इन है, लेकिन आवश्यक भूमिका में नहीं है, तो यह उन्हें वापस लॉगिन पृष्ठ पर भेजने में भ्रमित है।

ऐसा लगता है कि AuthorizeAttribute प्रमाणीकरण और प्रमाणीकरण conflates।

यह एएसपी.नेट एमवीसी में थोड़ी सी निगरानी की तरह लगता है, या क्या मुझे कुछ याद आ रही है?

मुझे एक DemandRoleAttribute बनाना है जो DemandRoleAttribute को अलग करता है। जब उपयोगकर्ता प्रमाणीकृत नहीं होता है, तो यह लॉगिन पृष्ठ पर भेजकर HTTP 401 देता है। जब उपयोगकर्ता लॉग इन होता है, लेकिन आवश्यक भूमिका में नहीं है, तो यह इसके बजाय एक NotAuthorizedResult बनाता है। वर्तमान में यह एक त्रुटि पृष्ठ पर रीडायरेक्ट करता है।

निश्चित रूप से मुझे यह करने की ज़रूरत नहीं थी?


जब इसे पहली बार विकसित किया गया था, System.Web.Mvc.AuthorizeAttribute सही काम कर रहा था - HTTP विनिर्देश के पुराने संशोधन "अनधिकृत" और "अनधिकृत" दोनों के लिए स्थिति कोड 401 का उपयोग करते थे।

मूल विनिर्देश से:

अगर अनुरोध में पहले से ही प्राधिकरण प्रमाण-पत्र शामिल हैं, तो 401 प्रतिक्रिया इंगित करती है कि उन प्रमाण-पत्रों के लिए प्राधिकरण को अस्वीकार कर दिया गया है।

वास्तव में, आप वहां भ्रम को देख सकते हैं - यह "प्रमाणीकरण" शब्द का उपयोग करता है जब इसका अर्थ "प्रमाणीकरण" होता है। हालांकि, रोजमर्रा की प्रैक्टिस में, उपयोगकर्ता को प्रमाणीकृत होने पर अधिकृत नहीं होने पर 403 निषिद्ध होने पर अधिक समझदारी होती है। यह संभावना नहीं है कि उपयोगकर्ता के पास क्रेडेंशियल्स का दूसरा सेट होगा जो उन्हें एक्सेस करेगा - खराब उपयोगकर्ता अनुभव।

अधिकांश ऑपरेटिंग सिस्टम पर विचार करें - जब आप किसी फ़ाइल को पढ़ने का प्रयास करते हैं तो आपको एक्सेस करने की अनुमति नहीं है, आपको लॉगिन स्क्रीन नहीं दिखाई दे रही है!

शुक्र है, अस्पष्टता को दूर करने के लिए HTTP विनिर्देशों को अपडेट किया गया था (जून 2014)।

"हाइपर टेक्स्ट ट्रांसपोर्ट प्रोटोकॉल (HTTP / 1.1) से: प्रमाणीकरण" (आरएफसी 7235):

401 (अनधिकृत) स्थिति कोड इंगित करता है कि अनुरोध लागू नहीं किया गया है क्योंकि इसमें लक्षित संसाधन के लिए वैध प्रमाणीकरण प्रमाण-पत्रों की कमी है।

"हाइपरटेक्स्ट ट्रांसफर प्रोटोकॉल (HTTP / 1.1) से: सेमेन्टिक्स एंड कंटेंट" (आरएफसी 7231):

403 (निषिद्ध) स्थिति कोड इंगित करता है कि सर्वर अनुरोध को समझ गया लेकिन इसे अधिकृत करने से इंकार कर दिया।

दिलचस्प बात यह है कि उस समय एएसपी.नेट एमवीसी 1 को जारी किया गया था AuthorizeAttribute का व्यवहार सही था। अब, व्यवहार गलत है - HTTP / 1.1 विनिर्देश तय किया गया था।

ASP.NET के लॉगिन पृष्ठ को पुनर्निर्देशित करने के प्रयास के बजाय, स्रोत पर समस्या को ठीक करना आसान है। आप अपनी वेबसाइट के डिफ़ॉल्ट नेमस्पेस (यह बहुत महत्वपूर्ण है) में एक ही नाम ( AuthorizeAttribute ) के साथ एक नई विशेषता बना सकते हैं, तो संकलक स्वचालित रूप से इसे एमवीसी के मानक के बजाय उठाएगा। बेशक, यदि आप उस दृष्टिकोण को लेना चाहते हैं तो आप हमेशा एक नया नाम दे सकते हैं।

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

अपने ग्लोबल.एक्सएक्स फ़ाइल के Application_EndRequest हैंडलर में इसे अपने आप में आज़माएं

if (HttpContext.Current.Response.Status.StartsWith("302") && HttpContext.Current.Request.Url.ToString().Contains("/<restricted_path>/"))
{
    HttpContext.Current.Response.ClearContent();
    Response.Redirect("~/AccessDenied.aspx");
}

यदि आप एस्पनेटकोर 2.0 का उपयोग करते हैं, तो इसका उपयोग करें:

using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Core
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class AuthorizeApiAttribute : Microsoft.AspNetCore.Authorization.AuthorizeAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var user = context.HttpContext.User;

            if (!user.Identity.IsAuthenticated)
            {
                context.Result = new UnauthorizedResult();
                return;
            }
        }
    }
}

दुर्भाग्यवश, आप एएसपी.नेट फॉर्म प्रमाणीकरण के डिफ़ॉल्ट व्यवहार से निपट रहे हैं। यहां एक कार्यवाही है (मैंने कोशिश नहीं की है) यहां चर्चा की गई है:

http://www.codeproject.com/KB/aspnet/Custon401Page.aspx

(यह एमवीसी के लिए विशिष्ट नहीं है)

मुझे लगता है कि ज्यादातर मामलों में सबसे अच्छा समाधान उपयोगकर्ता से पहले वहां पहुंचने की कोशिश करने से पहले अनधिकृत संसाधनों तक पहुंच प्रतिबंधित करना है। लिंक या बटन को हटाकर / भूरे रंग से निकालकर जो उन्हें इस अनधिकृत पृष्ठ पर ले जा सकता है।

एक अनधिकृत उपयोगकर्ता को पुनर्निर्देशित करने के लिए यह निर्दिष्ट करने के लिए विशेषता पर एक अतिरिक्त पैरामीटर होना शायद अच्छा होगा। लेकिन इस बीच, मैं प्राधिकरण एट्रिब्यूट को सुरक्षा नेट के रूप में देखता हूं।


इसे अपने लॉगिन पेज_ लोड फ़ंक्शन में जोड़ें:

// User was redirected here because of authorization section
if (User.Identity != null && User.Identity.IsAuthenticated)
    Response.Redirect("Unauthorized.aspx");

जब उपयोगकर्ता को रीडायरेक्ट किया जाता है लेकिन पहले ही लॉग इन होता है, तो यह अनधिकृत पृष्ठ दिखाता है। अगर वे लॉग इन नहीं हैं, तो यह लॉगिन पेज से गुज़रता है और दिखाता है।





authorization