asp.net-mvc - شرح - asp.net mvc ماهو




Asp.net MVC4: اعتماد على كل من وحدة التحكم والعمل (2)

أنت سألت:

إذا كان لدي سمة Authorize على كل من جهاز التحكم والإجراء ، فأيهما سيأخذ التأثير؟ على حد سواء؟

للإجابة على هذا ببساطة: كلا. يكون التأثير على AND التقييدان معًا. ساوضح لماذا أدناه ...

تفاصيل

لذلك ، هناك بعض الأسباب التي قد تجعلك تسأل هذا.

  1. تريد معرفة كيفية فرض قيد إضافي على الإجراء مقارنةً بالطريقة. على سبيل المثال
    • على مستوى جهاز التحكم ، فرض المستخدمين في دور "المستخدم"
    • على مستوى الإجراء ، يمكنك أيضًا فرض المستخدمين في الدور "مشرف"
  2. تريد استبدال قيود وحدة التحكم على مستوى الإجراء
  3. تريد إزالة قيد وحدة التحكم على مستوى الإجراء وإتاحة الطريقة للمستخدمين المجهولين

لم تقم بتحديد إصدار MVC الخاص بك ، لذلك سوف أفترض أحدث إصدار من اليوم (MVC 4.5). ومع ذلك ، لن يؤدي ذلك إلى تغيير الإجابة كثيرًا حتى لو كنت تستخدم MVC 3.

[Anonymous] يتجاوز تحكم [Authorize] (حالة 3)

الحالة 3. لست بحاجة إلى تغطية (استخدام [AllowAnonymous] ) لأنه تمت الإجابة عليه في جميع أنحاء SO وعلى جميع أنحاء الويب بالفعل. يكفي القول: إذا قمت بتحديد [AllowAnonymous] على أحد الإجراءات ، [AllowAnonymous] هذا الإجراء عامًا حتى لو كان جهاز التحكم [Authorize] عليه.

يمكنك أيضًا جعل موقع ويب بالكامل خاضعًا لتفويض باستخدام عامل تصفية عام ، واستخدام AllowAnonymous على الإجراءات أو وحدات التحكم القليلة التي تريد جعلها عامة.

[Authorize] هو مادة مضافة (الحالة 1)

الحالة 1 سهلة. خذ وحدة التحكم التالية كمثال:

[Authorize(Roles="user")]
public class HomeController : Controller {
    public ActionResult AllUsersIndex() {
        return View();
    }

    [Authorize(Roles = "admin")]
    public ActionResult AdminUsersIndex() {
        return View();
    }
}

بشكل افتراضي [Authorize(Roles="user")] يجعل [Authorize(Roles="user")] جميع الإجراءات في وحدة التحكم متوفرة للحسابات في دور "المستخدم" فقط. ولذلك ، يجب الوصول إلى AllUsersIndex في دور "المستخدم". ومع ذلك للوصول إلى AdminUsersIndex يجب أن تكون كلاهما في "المستخدم" ودور "المسؤول". فمثلا:

  • اسم المستخدم: بوب ، الأدوار: مستخدم ، لا يمكن الوصول إلى AdminUsersIndex ، ولكن يمكن الوصول إلى AllUsersIndex
  • اسم المستخدم: Jane ، Roles: admin ، لا يمكن الوصول إلى AdminUsersIndex أو AllUsersIndex
  • اسم المستخدم: تيم ، الأدوار: المستخدم AdminUsersIndex ، يمكن الوصول إلى AdminUsersIndex و AllUsersIndex

يوضح هذا أن السمة [Authorize] مضافة. وينطبق ذلك أيضًا على خاصية Users الخاصة بالسمة ، والتي يمكن دمجها مع Roles لجعلها أكثر تقييدًا.

هذا السلوك بسبب الطريقة التي تعمل سمات التحكم والعمل. يتم تقييد الخصائص معًا وتطبيقها في وحدة التحكم في الأمر ثم الإجراء. إذا رفض الأول الترخيص ، فعندئذ يمكنك التحكم في المرتجعات ولا يتم استدعاء سمة الإجراء. إذا كان الشخص الأول يمرر التفويض ، فسيتم بعد ذلك فحص الترخيص الثاني أيضًا. يمكنك إلغاء هذا الترتيب من خلال تحديد Order (على سبيل المثال [Authorize(Roles = "user", Order = 2)] ).

تجاوز [Authorize] (الحالة 2)

الحالة 2 أكثر تعقيدًا. أذكر من أعلاه أن يتم فحص سمات [Authorize] بالترتيب (Global ثم) وحدة التحكم ثم الإجراء. أول واحد للكشف عن أن المستخدم غير مؤهل ليكون الفوز المأذون ، لا يتم استدعاء الآخرين.

طريقة واحدة حول هذا هو تحديد اثنين من السمات الجديدة على النحو التالي. لا يقوم [OverrideAuthorize] بأي شيء آخر سوى التأجيل إلى [Authorize] ؛ الغرض الوحيد منه هو تحديد نوع يمكننا التحقق منه. يتيح لنا [DefaultAuthorize] التحقق لمعرفة ما إذا كان الإجراء الذي يتم استدعاءه في الطلب مزينًا بـ [OverrideAuthorize] . إذا تم ذلك بعد ذلك ، فإننا نلجأ إلى فحص تفويض الإجراء ، وإلا فإننا نتحقق من فحص مستوى وحدة التحكم.

public class DefaultAuthorizeAttribute : AuthorizeAttribute {
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var action = filterContext.ActionDescriptor;
        if (action.IsDefined(typeof(OverrideAuthorizeAttribute), true)) return;

        base.OnAuthorization(filterContext);
    }
}
public class OverrideAuthorizeAttribute : AuthorizeAttribute {
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
    }
}

يمكننا بعد ذلك استخدامه كما يلي:

[DefaultAuthorize(Roles="user")]
public class HomeController : Controller {
    // Available to accounts in the "user" role
    public ActionResult AllUsersIndex() {
        return View();
    }
    // Available only to accounts both in the "user" and "admin" role
    [Authorize(Roles = "admin")]
    public ActionResult AdminUsersIndex() {
        return View();
    }
    // Available to accounts in the "superuser" role even if not in "user" role
    [OverrideAuthorize(Roles = "superuser")]
    public ActionResult SuperusersIndex() {
        return View();
    }
}

في المثال أعلاه ، يتوفر SuperusersIndex لحساب يحتوي على دور "المستخدم المتميز" ، حتى إذا لم يكن لديه دور "المستخدم".

إذا كان لدي سمة التفويض على كل من جهاز التحكم والإجراء ، فأيهما سيأخذ التأثير؟ أو كلاهما ساري المفعول؟


أود أن أضيف شيئًا إلى تجاوز [أذن] (الحالة 2)

يعمل كل من OverrideAuthorizeAttribute و DefaultAuthorizeAttribute بشكل جيد ، لكنني أكتشف أنه يمكنك أيضًا استخدام OverrideAuthorizationAttribute الذي يتجاوز عوامل تصفية التفويض المحددة في مستوى أعلى.

[Authorize(Roles="user")]
public class HomeController : Controller {
    // Available to accounts in the "user" role
    public ActionResult AllUsersIndex() {
        return View();
    }
    // Available only to accounts both in the "user" and "admin" role
    [Authorize(Roles = "admin")]
    public ActionResult AdminUsersIndex() {
        return View();
    }
    // Available to accounts in the "superuser" role even if not in "user" role
    [OverrideAuthorization()]
    [Authorize(Roles = "superuser")]
    public ActionResult SuperusersIndex() {
        return View();
    }
}




authorize-attribute