Câu trả lời chấp nhận hiện nay không phải là giải pháp an toàn nhất vì nó đòi hỏi các nhà phát triển để luôn nhớ để thừa kế mà lớp cơ sở mới cho bất kỳ bộ điều khiển mới hoặc hành động ("danh sách đen"; cho phép người dùng truy cập vào tất cả mọi thứ trừ một hành động bị giới hạn theo cách thủ công). Điều này đặc biệt gây ra vấn đề khi các nhà phát triển mới, không quen thuộc với các nghi thức của bạn, được giới thiệu cho dự án. Thật dễ dàng để quên kế thừa các lớp điều khiển thích hợp nếu thực hiện theo cách đó, đặc biệt là sau khi đã rời mắt khỏi dự án trong nhiều tuần, vài tháng hoặc nhiều năm. Nếu một nhà phát triển quên kế thừa, nó không phải là rõ ràng rằng có một lỗ hổng bảo mật trong dự án.
Một giải pháp an toàn hơn cho vấn đề này là để từ chối truy cập vào tất cả yêu cầu, sau đó trang trí mỗi hành động với vai trò được phép truy cập vào các hành động ("danh sách trắng"; ngăn chặn truy cập đến tất cả người dùng trừ khi tự cho phép). Bây giờ nếu một nhà phát triển quên lập danh sách trắng cho phép phù hợp, người dùng sẽ cho bạn biết và nó đơn giản như nhìn vào các bộ điều khiển khác để được nhắc nhở về cách cung cấp quyền truy cập thích hợp. Tuy nhiên, ít nhất không có lỗ hổng bảo mật lớn.
Trong file App_Start/FilterConfig.cs, sửa đổi các lớp FilterConfig:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
...
//Deny access to all controllers and actions so that only logged in Administrators can access them by default
filters.Add(new System.Web.Mvc.AuthorizeAttribute() { Roles = "Administrator" });
}
Điều này làm cho tất cả những hành động không thể tiếp cận trừ khi người dùng đang đăng nhập như một quản trị viên. Sau đó, đối với mỗi hành động mà bạn muốn người dùng được ủy quyền khác có quyền truy cập, bạn chỉ cần trang trí nó với [OverrideAuthorization]
và [Authorize]
.
Trong logic nghiệp vụ của bạn, điều này cho phép bạn sử dụng thuộc tính Ủy quyền theo nhiều cách khác nhau mà không cần phải lo lắng về việc người dùng trái phép truy cập bất kỳ chức năng nào. Dưới đây là một số ví dụ.
Ví dụ 1 - Chỉ người dùng Quản trị viên và người điều phối đã đăng nhập mới được phép truy cập Index()
Phương thức lấy và đăng.
public class MarkupCalculatorController : Controller //Just continue using the default Controller class.
{
// GET: MarkupCalculator
[OverrideAuthorization]
[Authorize(Roles = "Administrator,Dispatcher")]
public ActionResult Index()
{
//Business logic here.
return View(...);
}
// POST: DeliveryFeeCalculator
[HttpPost]
[ValidateAntiForgeryToken]
[OverrideAuthorization]
[Authorize(Roles = "Administrator,Dispatcher")]
public ActionResult Index([Bind(Include = "Price,MarkedupPrice")] MarkupCalculatorVM markupCalculatorVM)
{
//Business logic here.
return View(...);
}
}
Ví dụ 2 - Chỉ chứng thực người dùng sẽ được phép truy cập vào phương pháp điều khiển Trang chủ của Index()
.
public class HomeController : Controller
{
[OverrideAuthorization]
[Authorize] //Allow all authorized (logged in) users to use this action
public ActionResult Index()
{
return View();
}
}
Ví dụ 3 - Những người dùng không (ví dụ: người dùng ẩn danh) có thể được phép phương pháp truy cập bằng cách sử dụng các thuộc tính [AllowAnonymous]
. Điều này cũng tự động ghi đè bộ lọc chung mà không cần thuộc tính [OverrideAuthorization]
.
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
...
}
Ví dụ 4 - Chỉ quản trị viên sẽ được phép tiếp cận với phương pháp mà thiếu thuộc tính [Authorize]
.
public class LocationsController : Controller
{
// GET: Locations
public ActionResult Index()
{
//Business logic here.
return View(...);
}
}
Một số lưu ý.
Bạn phải sử dụng thuộc tính [OverrideAuthorization]
nếu bạn muốn giới hạn quyền truy cập vào một hành động cụ thể đối với các vai trò cụ thể. Nếu không, thuộc tính thuộc tính [Authorize]
sẽ bị bỏ qua và chỉ vai trò mặc định (Quản trị viên trong ví dụ của tôi) sẽ được cho phép, ngay cả khi bạn chỉ định các vai trò khác (ví dụ: Người điều phối, v.v.) vì bộ lọc toàn cục. Bất kỳ người dùng trái phép nào đều sẽ được chuyển hướng đến màn hình đăng nhập.
Sử dụng thuộc tính [OverrideAuthorization]
làm cho tác vụ bỏ qua bộ lọc chung mà bạn đã đặt. Do đó, bạn phải áp dụng lại thuộc tính [Authorize]
bất cứ khi nào bạn sử dụng ghi đè để hành động vẫn an toàn.
Về toàn bộ khu vực và điều khiển
Để hạn chế bởi các khu vực, như bạn đang yêu cầu, đặt [OverrideAuthorization]
và [Authorize]
thuộc tính trên bộ điều khiển thay vì những hành động cá nhân.
Xem bài đăng trên blog của tôi [Đảm bảo ứng dụng ASP.NET MVC 3 của bạn] (http://blogs.msdn.com/b/rickandy/archive/2011/05/02/securing-your-asp-net-mvc- 3-application.aspx) – RickAndMSFT
Xem bài đăng trên blog của tôi Đảm bảo ứng dụng ASP.NET MVC 4 của bạn và Thuộc tính AllowAnonymous mới – RickAndMSFT
Liên kết cho nhận xét cuối cùng của Rick -> http://blogs.msdn.com/b/rickandy/archive/2012/ 03/23/securing-your-asp-net-mvc-4-app-and-the-new-allowanonymous-attribute.aspx –