सवाल एएसपी.नेट एमवीसी - लॉगिन पेज पर अनधिकृत त्रुटि कैसे दिखाएं?


मेरे एएसपी.नेट एमवीसी ऐप में, मेरे पास सजाए गए अधिकांश नियंत्रक हैं

[Authorize(Roles="SomeGroup")]

जब कोई उपयोगकर्ता किसी चीज़ तक पहुंचने के लिए अधिकृत नहीं होता है, तो उन्हें "~ / लॉगिन" पर भेजा जाता है जो मेरे खाता नियंत्रक पर लॉगिन क्रिया है।

मैं कैसे निर्धारित कर सकता हूं कि उपयोगकर्ता अधिकृत नहीं होने के कारण लॉगिन पृष्ठ पर पहुंच गया है ताकि मैं उचित त्रुटि दिखा सकूं?


44
2017-09-30 15:07


मूल




जवाब:


आप देख सकते हैं ?ReturnUrl=  querystring मान, या आप अपना खुद का प्राधिकरण फ़िल्टर बना सकते हैं और एक फ़ील्ड सेट कर सकते हैं TempData कारण बताते हैं।

यहां एक साधारण कस्टम फ़िल्टर है जो चाल करेगा:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{

    // NOTE: This is not thread safe, it is much better to store this
    // value in HttpContext.Items.  See Ben Cull's answer below for an example.
    private bool _isAuthorized;

    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        _isAuthorized = base.AuthorizeCore(httpContext);
        return _isAuthorized;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if(!_isAuthorized)
        {
            filterContext.Controller.TempData.Add("RedirectReason", "Unauthorized");
        }
    }
}

फिर आपके विचार में, आप ऐसा कुछ कर सकते हैं:

@if(TempData["RedirectReason"] == "Unauthorized")
{
    <b>You don't have permission to access that area</b>
}

(हालांकि मैं इन जादू तारों की तुलना में बेहतर दृष्टिकोण की सिफारिश करता हूं, लेकिन आपको बिंदु मिल जाता है)


28
2017-09-30 15:21



कार्यान्वित करने में आसान है और यह काम करता है। धन्यवाद। - Ronnie Overby
धन्यवाद बेन, मैं अपनी तरफ से इसे लागू करता हूं और बहुत अच्छी तरह से काम करता हूं! - Gabriel Mongeon
यह उत्तर स्वीकार किया गया है, लेकिन यह थ्रेड सुरक्षित नहीं है, कृपया अधिक जानकारी के लिए नीचे उत्तर देखें। कृपया थ्रेड सुरक्षित होने के लिए अपना कोड अपडेट करें, बहुत से डेवलपर अन्य उत्तरों नहीं पढ़ सकते हैं और अपना सर्वश्रेष्ठ उपयोग कर सकते हैं। - Serhiy Prysyazhnyy
इस प्रभाव में एक टिप्पणी जोड़ा गया। - Ben Scheirman
मैंने इस टिप्पणी को तब देखा जब मेरे प्रोजेक्ट में उस कोड की प्रतिलिपि बनाई गई और इसे पढ़ने-रीफैक्टर करना शुरू कर दिया :) - EvAlex


अद्यतन (जून 2015): @ डैनियल-लिडस्ट्रॉम ने सही ढंग से बताया है कि आपको ASP.NET MVC एप्लिकेशन में Response.Redirect का उपयोग नहीं करना चाहिए। क्यों, इस लिंक को देखने के बारे में अधिक जानकारी के लिए: Response.Redirect और एएसपी.नेट एमवीसी - मिश्रण मत करो

अद्यतन (सितंबर 2014): मुझे यकीन नहीं है कि जब HandleUnauthorizedRequest AuthorizeAttribute में जोड़ा गया था, लेकिन किसी भी तरह से मैं AuthorizeRedirect कोड को कुछ छोटे और सरल में परिष्कृत करने में सक्षम हूं।

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeRedirect : AuthorizeAttribute
{
    public string RedirectUrl = "~/Error/Unauthorized";

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectResult(RedirectUrl);
        }
    }
}

मूल उत्तर नीचे (अभी भी पूरी तरह कार्यात्मक)

मैंने यह जवाब यहां छोड़ा है क्योंकि यह आपको अभी भी अंतर्दृष्टि देता है कि प्राधिकरण पाइपलाइन कैसे काम करती है।

किसी भी व्यक्ति के लिए अभी भी लैंडिंग के लिए, मैंने बेन Scheirman के जवाब को स्वचालित रूप से एक अनधिकृत पृष्ठ पर रीडायरेक्ट करने के लिए संपादित किया है जब उपयोगकर्ता लॉग इन है लेकिन अधिकृत नहीं है। आप नाम पैरामीटर RedirectUrl का उपयोग कर रीडायरेक्ट पथ बदल सकते हैं।

संपादित करें: मैंने सलाह के लिए समाधान थ्रेड-सुरक्षित धन्यवाद दिया है Tarynn तथा MSDN

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeRedirect : AuthorizeAttribute
{
    private const string IS_AUTHORIZED = "isAuthorized";

    public string RedirectUrl = "~/error/unauthorized";

    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        bool isAuthorized = base.AuthorizeCore(httpContext);

        httpContext.Items.Add(IS_AUTHORIZED, isAuthorized);

        return isAuthorized;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        var isAuthorized = filterContext.HttpContext.Items[IS_AUTHORIZED] != null 
            ? Convert.ToBoolean(filterContext.HttpContext.Items[IS_AUTHORIZED]) 
            : false;

        if (!isAuthorized && filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.RequestContext.HttpContext.Response.Redirect(RedirectUrl);
        }
    }
}

75
2018-03-08 23:15



एमएसडीएन से: AuthorizeAttribute से प्राप्त करना यदि आप AuthorizeAttribute क्लास से प्राप्त करते हैं, तो व्युत्पन्न प्रकार थ्रेड सुरक्षित होना चाहिए। इसलिए, राज्य के प्रकार के उदाहरण में उदाहरण न दें (उदाहरण के लिए, एक उदाहरण फ़ील्ड में) जब तक कि वह राज्य सभी अनुरोधों पर लागू न हो। इसके बजाए, आइटम प्रॉपर्टी में प्रति अनुरोध राज्य संग्रह करें, जो AuthorizeAttribute को संदर्भित संदर्भ ऑब्जेक्ट्स के माध्यम से सुलभ है। _is अधिकृत एक आवृत्ति क्षेत्र नहीं है? - Tarynn
यह सही काम करता है लेकिन मैं यहां कुछ नोट का उल्लेख करना चाहता हूं। यह मुझे 2 घंटे से अधिक समय लेता है क्योंकि कुछ गलती लागू करते समय। - फिल्टर की तरह फिल्टर में जोड़ें मत जोड़ें। जोड़ें (नया AuthorizeRedirect ()); - नियंत्रक में इसे कार्यान्वित करें: [AuthorizeRedirect (भूमिकाएं = "व्यवस्थापक")] पब्लिक क्लास रोलकंट्रोलर: नियंत्रक। लागू नहीं करें [प्राधिकरण (भूमिकाएं = "व्यवस्थापक")] सार्वजनिक वर्ग रोलकंट्रोलर: नियंत्रक - Grey Wolf
कक्षा में रीडायरेक्ट निर्भरता रखने के बजाय, मैंने इसे बदल दिया filterContext.RequestContext.HttpContext.AddError(new HttpException(403, "You have no power here...")); जो मुझे उपयोग करने देता है customError web.config से। मैं अभी भी चाहता हूं कि वास्तव में एक वापसी करने का एक तरीका था 403 के स्थान पर 302 हालांकि। - MisterIsaak
@Dabbas Nope निश्चित रूप से बस अगर ()। यह कह रहा है कि यदि आप प्रमाणीकृत हैं (लॉग इन हैं) लेकिन अधिकृत नहीं हैं (अनुमति है) तो उस पृष्ठ पर रीडायरेक्ट करें जो कहता है "मुझे पता है कि आप लॉग इन हैं और यहां रहने की अनुमति नहीं है"। - Ben Cull
filterContext.RequestContext.HttpContext.Response.Redirect (RedirectUrl) - मेरे लिए यह वास्तव में रीडायरेक्ट करता है फिर भी "System.Web.HttpException (0x80004005) फेंकता है: HTTP शीर्षलेख भेजे जाने के बाद रीडायरेक्ट नहीं किया जा सकता है।" हुड के नीचे। क्या इससे बचा जा सकता है और यदि ऐसा है तो कैसे? - ProNotion


बेन कूल की विधि अच्छी तरह से काम करती है, लेकिन याद रखें कि दो AuthorizeAttribute क्लासेस हैं - एक System.Web.HTTP (वेब ​​एपीआई द्वारा उपयोग किया जाता है), और दूसरा System.Web.Mvc में। बेन की विधि System.Web.Mvc क्लास का उपयोग करती है। स्पष्टता के लिए, मैं पूरी तरह योग्यता प्राप्त पथ का उपयोग करने का सुझाव देता हूं।

यदि आप एमवीसी के साथ वेब एपीआई का उपयोग कर रहे हैं, तो आपको दो फिल्टर लागू करने की आवश्यकता होगी:

public class AuthorizeRedirectMVCAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectResult("~/Account/AccessDenied");
        }
    }
}

public class AuthorizeRedirectAPIAttribute : System.Web.Http.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        base.HandleUnauthorizedRequest(actionContext);

        if (actionContext.RequestContext.Principal.Identity.IsAuthenticated)
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden);
        }
    }
}

ध्यान दें कि एएसपीनेट आपको एपीआई फ़िल्टर के साथ अपने एमवीसी नियंत्रक को सजाने देगा - यह आपके द्वारा अपेक्षित तरीके से काम नहीं करेगा, इसलिए अपने गुणों के नामों को स्पष्ट रखें।


5
2018-02-05 15:59





यदि आपके पास नियंत्रक है और आप कोड में यूआरएल नहीं चाहते हैं तो आप इस तरह से रीडायरेक्ट कर सकते हैं। यह ब्राउज़र के पता बार में यूआरएल नहीं बदलेगा, इसलिए उपयोगकर्ता अनधिकृत पृष्ठ के लिए यूआरएल कभी नहीं देख पाएगा। यह एमवीसी 3 में लिखा गया था। यह विधि तब भी काम करेगी जब आप उन्हें लॉगिन पेज पर रीडायरेक्ट करना चाहते हैं या यदि आप उन्हें किसी पृष्ठ पर रीडायरेक्ट करना चाहते हैं तो बस उन्हें बताएं कि वे अधिकृत नहीं हैं। मेरे पास इस कार्यक्रम में सेक्शन था कि कुछ उपयोगकर्ता के पास अधिकार नहीं थे लेकिन वे लॉग इन थे इसलिए मैंने यही उपयोग किया।

public class AuthorizedRedirect : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool isAuthorized = base.AuthorizeCore(httpContext);
        return isAuthorized;
    }
protect override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    filterContext.RequestContext.RouteData.Values["controller"] = "error";
    filterContext.Result = new ViewResult { ViewName = "unauthorized" };
}

4
2017-09-26 18:58



साझा दृश्य में संदेश दिखाने के लिए एक और विविधता के रूप में, उदा। var vr = new ViewResult(); vr.ViewName = "Info"; vr.ViewBag.Message = "You are unauthorized for this page; contact us. "; filterContext.Result = vr; - subsci


और एक सरल संस्करण जो फॉर्म प्रमाणीकरण सेटिंग्स का उपयोग करता है। उन लोगों के लिए जो अनुबंध से परिचित नहीं हैं, अनुबंध। आवश्यकताएं एक .NET 4 अतिरिक्त है। उपयोग करने के लिए पेशेवरों और विपक्ष संहिता अनुबंध

public class RequiresAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        Contract.Requires(filterContext != null);

        HttpContextBase context = filterContext.RequestContext.HttpContext;

        if (context.User.Identity.IsAuthenticated)
        {
            // user does not possess the required role permission
            string url = context.GetCustomErrorUrl(401);
            context.Response.Redirect(url);
        }
        else
        {

            // redirect the user to the login page
            string extraQueryString  = context.Request.RawUrl;
            FormsAuthentication.RedirectToLoginPage(extraQueryString);
        }
    }
}

2
2017-09-27 00:21





Divide_byzero के उत्तर से आगे जाकर भले ही आपके पास नियंत्रक न हो, फिर भी आप रीडायरेक्ट को बदलने के लिए हैंडलयूनाधिकृत रिक्वेस्ट का उपयोग कर सकते हैं।

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AuthoriseRedirect : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.Redirect("UrlToRedirectTo");
        }
    }

यदि आपके पास विरासत वेबफॉर्म साइट है तो आप काम में आते हैं कि आप लंबे समय तक एमवीसी में परिवर्तित हो जाएंगे .....!


1
2017-11-18 06:35





मुझे पसंद है ब्रायन वेंडर प्लाट्स ने क्या पोस्ट किया, बस कुछ सुधार जोड़े:

/// <summary>
/// Authorize or redirect to an unauthorized MVC action if the user does not have the required roles
/// (an unauthenticated user will be redirected to the defualt sign in action)
/// <para>Decorate an action or a controller like this [AuthorizeAndRedirect(Roles = "RoleName")]</para>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class AuthorizeOrRedirectAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            var routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "Unauthorized");
            filterContext.Result = new RedirectToRouteResult(routeData.Values);
        }
    }
}

/// <summary>
/// Authorize or redirect to an unauthorized API action if the user does not have the required roles
/// (an unauthenticated user will be redirected to the defualt sign in action)
/// <para>Decorate an action or a controller like this [AuthorizeAndRedirect(Roles = "RoleName")]</para>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class AuthorizeOrRedirectApiFilterAttribute : System.Web.Http.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        base.HandleUnauthorizedRequest(actionContext);

        if (actionContext.RequestContext.Principal.Identity.IsAuthenticated)
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        }
    }
}

0
2018-04-07 20:07