เมื่อได้รับการพัฒนาขึ้นครั้งแรก System.Web.Mvc.AuthorizeAttribute กำลังทำสิ่งที่ถูกต้อง - การแก้ไขเก่าของข้อกำหนด HTTP ที่ใช้รหัสสถานะ 401 สำหรับทั้ง "ไม่ได้รับอนุญาต" และ "ไม่ได้รับการรับรองความถูกต้อง"
จากสเปคเดิม:
หากคำร้องขอนั้นมีข้อมูลประจำตัวการอนุญาตแล้วการตอบสนอง 401 บ่งชี้ว่าการอนุญาตนั้นถูกปฏิเสธสำหรับข้อมูลรับรองเหล่านั้น
ในความเป็นจริงคุณสามารถเห็นความสับสนที่นั่น - มันใช้คำว่า "การอนุญาต" เมื่อมันหมายถึง "การรับรองความถูกต้อง" อย่างไรก็ตามในทางปฏิบัติในชีวิตประจำวันมันเหมาะสมกว่าที่จะส่งคืน 403 สิ่งต้องห้ามเมื่อผู้ใช้รับรองความถูกต้อง แต่ไม่ได้รับอนุญาต ไม่น่าเป็นไปได้ที่ผู้ใช้จะมีหนังสือรับรองชุดที่สองที่จะให้พวกเขาเข้าถึง - ประสบการณ์ผู้ใช้ที่ไม่ดีรอบตัว
พิจารณาระบบปฏิบัติการส่วนใหญ่ - เมื่อคุณพยายามอ่านไฟล์ที่คุณไม่มีสิทธิ์เข้าถึงคุณจะไม่เห็นหน้าจอเข้าสู่ระบบ!
โชคดีที่ข้อมูลจำเพาะ HTTP ได้รับการอัปเดต (มิถุนายน 2014) เพื่อลบความคลุมเครือ
จาก "Hyper Text Transport Protocol (HTTP / 1.1): การตรวจสอบความถูกต้อง" (RFC 7235):
รหัสสถานะ 401 (ไม่ได้รับอนุญาต) บ่งชี้ว่าการร้องขอนั้นไม่ได้ถูกนำไปใช้เพราะมันไม่มีข้อมูลรับรองการตรวจสอบสิทธิ์ที่ถูกต้องสำหรับทรัพยากรเป้าหมาย
จาก "Hypertext Transfer Protocol (HTTP / 1.1): ความหมายและเนื้อหา" (RFC 7231):
รหัสสถานะ 403 (ต้องห้าม) ระบุว่าเซิร์ฟเวอร์เข้าใจคำขอ แต่ปฏิเสธที่จะอนุญาต
น่าสนใจพอในขณะนั้น ASP.NET MVC 1 ถูกเผยแพร่พฤติกรรมของ AuthorizeAttribute นั้นถูกต้อง ตอนนี้พฤติกรรมไม่ถูกต้อง - ข้อมูลจำเพาะ HTTP / 1.1 ได้รับการแก้ไขแล้ว
แทนที่จะพยายามเปลี่ยนหน้าการเข้าสู่ระบบของ ASP.NET จะเป็นการง่ายกว่าที่จะแก้ไขปัญหาที่แหล่งที่มา คุณสามารถสร้างแอททริบิวใหม่ด้วยชื่อเดียวกัน ( AuthorizeAttribute
) ในเนมสเปซเริ่มต้นของเว็บไซต์ของคุณ (สำคัญมาก) จากนั้นคอมไพเลอร์จะเลือกโดยอัตโนมัติแทน MVC มาตรฐาน แน่นอนว่าคุณสามารถตั้งชื่อใหม่ให้แอตทริบิวต์ได้เสมอหากคุณต้องการใช้วิธีการนั้น
[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);
}
}
}