Khi được phát triển lần đầu tiên, System.Web.Mvc.AuthorizeAttribution đã làm đúng - các phiên bản cũ hơn của đặc tả HTTP đã sử dụng mã trạng thái 401 cho cả "không được phép" và "không được xác thực".
Từ đặc điểm kỹ thuật ban đầu:
Nếu yêu cầu đã bao gồm thông tin xác thực ủy quyền, thì phản hồi 401 cho biết rằng ủy quyền đã bị từ chối cho các thông tin đăng nhập đó.
Trên thực tế, bạn có thể thấy sự nhầm lẫn ngay tại đó - nó sử dụng từ "ủy quyền" khi nó có nghĩa là "xác thực". Tuy nhiên, trong thực tế hàng ngày, việc trả lại 403 Cấm khi người dùng được xác thực nhưng không được ủy quyền sẽ có ý nghĩa hơn. Người dùng không có khả năng sẽ có một bộ thông tin xác thực thứ hai sẽ cung cấp cho họ quyền truy cập - trải nghiệm người dùng xấu xung quanh.
Hãy xem xét hầu hết các hệ điều hành - khi bạn cố đọc một tệp mà bạn không có quyền truy cập, bạn sẽ không hiển thị màn hình đăng nhập!
Rất may, các thông số kỹ thuật HTTP đã được cập nhật (tháng 6 năm 2014) để loại bỏ sự mơ hồ.
Từ "Giao thức truyền tải siêu văn bản (HTTP / 1.1): Xác thực" (RFC 7235):
Mã trạng thái 401 (Không được phép) cho biết rằng yêu cầu chưa được áp dụng vì nó thiếu thông tin xác thực hợp lệ cho tài nguyên đích.
Từ "Giao thức truyền siêu văn bản (HTTP / 1.1): Ngữ nghĩa và nội dung" (RFC 7231):
Mã trạng thái 403 (Bị cấm) chỉ ra rằng máy chủ hiểu yêu cầu nhưng từ chối ủy quyền.
Thật thú vị, tại thời điểm ASP.NET MVC 1 được phát hành, hành vi của AuthorizeAttribution là chính xác. Bây giờ, hành vi không chính xác - đặc tả HTTP / 1.1 đã được sửa.
Thay vì cố gắng thay đổi chuyển hướng trang đăng nhập của ASP.NET, việc khắc phục sự cố tại nguồn dễ dàng hơn. Bạn có thể tạo một thuộc tính mới có cùng tên ( AuthorizeAttribute
) trong không gian tên mặc định của trang web của bạn (điều này rất quan trọng), sau đó trình biên dịch sẽ tự động chọn nó thay vì tiêu chuẩn của MVC. Tất nhiên, bạn luôn có thể đặt cho thuộc tính một tên mới nếu bạn muốn sử dụng phương pháp đó.
[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);
}
}
}