Tôi đang kế thừa từ System.Web.Http.AuthorizeAttribute để tạo một ủy quyền tùy chỉnh/xác thực thường trình để đáp ứng một số yêu cầu bất thường cho một ứng dụng web được phát triển bằng ASP.NET MVC 4. Điều này bổ sung tính bảo mật cho Web API được sử dụng cho các cuộc gọi Ajax từ máy khách web. Các yêu cầu là:Làm thế nào để tùy chỉnh ASP.NET Web API AuthorizeAttribute cho các yêu cầu bất thường
- Người dùng phải đăng nhập mỗi khi họ thực hiện một giao dịch để xác minh ai đó đã không đi đến các máy trạm sau khi ai đó có đăng nhập và bỏ đi.
- Vai trò không thể được gán cho các phương thức dịch vụ web vào thời gian chương trình. Họ phải được chỉ định vào thời gian chạy để quản trị viên có thể định cấu hình điều này. Thông tin này được lưu trữ trong cơ sở dữ liệu hệ thống.
Máy khách web là single page application (SPA) để xác thực biểu mẫu điển hình không hoạt động tốt, nhưng tôi đang cố gắng sử dụng lại nhiều khuôn khổ bảo mật ASP.NET như tôi có thể để đáp ứng các yêu cầu. Tùy chỉnh AuthorizeAttribute hoạt động tốt cho yêu cầu 2 khi xác định vai trò nào được liên kết với phương thức dịch vụ web. Tôi chấp nhận ba tham số, tên ứng dụng, tên tài nguyên và hoạt động để xác định các vai trò nào được liên kết với một phương thức.
public class DoThisController : ApiController
{
[Authorize(Application = "MyApp", Resource = "DoThis", Operation = "read")]
public string GetData()
{
return "We did this.";
}
}
tôi ghi đè lên các phương pháp OnAuthorization để có được những vai trò và xác thực người dùng. Vì người dùng phải được xác thực cho mỗi giao dịch, tôi giảm bớt cuộc trò chuyện qua lại bằng cách thực hiện xác thực và ủy quyền trong cùng một bước. Tôi nhận được thông tin đăng nhập của người dùng từ máy khách web bằng cách sử dụng xác thực cơ bản để chuyển các thông tin đăng nhập được mã hóa trong tiêu đề HTTP. Vì vậy, phương pháp OnAuthorization của tôi trông như thế này:
public override void OnAuthorization(HttpActionContext actionContext)
{
string username;
string password;
if (GetUserNameAndPassword(actionContext, out username, out password))
{
if (Membership.ValidateUser(username, password))
{
FormsAuthentication.SetAuthCookie(username, false);
base.Roles = GetResourceOperationRoles();
}
else
{
FormsAuthentication.SignOut();
base.Roles = "";
}
}
else
{
FormsAuthentication.SignOut();
base.Roles = "";
}
base.OnAuthorization(actionContext);
}
GetUserNameAndPassword lấy các chứng chỉ từ tiêu đề HTTP. Sau đó, tôi sử dụng Membership.ValidateUser để xác thực thông tin xác thực. Tôi có nhà cung cấp dịch vụ thành viên tùy chỉnh và nhà cung cấp vai trò được cắm vào để truy cập cơ sở dữ liệu tùy chỉnh. Nếu người dùng được xác thực thì tôi lấy lại vai trò cho tài nguyên và hoạt động. Từ đó, tôi sử dụng cơ sở OnAuthorization để hoàn tất quy trình cấp phép. Đây là nơi nó bị hỏng.
Nếu người dùng được xác thực, tôi sử dụng các phương thức xác thực biểu mẫu chuẩn để đăng nhập người dùng trong (FormsAuthentication.SetAuthCookie) và nếu họ không đăng xuất được (FormsAuthentication.SignOut). Nhưng vấn đề dường như là cơ sở Lớp OnAuthorization không có quyền truy cập vào Hiệu trưởng được cập nhật sao cho Được xác thực được đặt thành giá trị chính xác. Nó luôn luôn là một bước phía sau. Và tôi đoán là nó đang sử dụng một số giá trị được lưu trong bộ nhớ cache mà không được cập nhật cho đến khi có một chuyến đi khứ hồi tới máy khách web.
Vì vậy, tất cả điều này dẫn đến câu hỏi cụ thể của tôi là, liệu có một cách khác để thiết lập IsAuthenticated với giá trị chính xác cho hiện tại Principal mà không sử dụng cookie? Dường như với tôi rằng cookie không thực sự áp dụng trong trường hợp cụ thể này, nơi tôi phải xác thực mọi lúc.Lý do tôi biết IsAuthenticated không được thiết lập với giá trị đúng là tôi cũng ghi đè phương pháp HandleUnauthorizedRequest này:
protected override void HandleUnauthorizedRequest(HttpActionContext filterContext)
{
if (((System.Web.HttpContext.Current.User).Identity).IsAuthenticated)
{
filterContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
này cho phép tôi để trả lại một mã trạng thái của Tử Cấm cho khách hàng web nếu sự thất bại là do ủy quyền thay vì xác thực và nó có thể phản hồi cho phù hợp.
Vì vậy, cách thích hợp để đặt IsAuthenticated cho hiện tại Nguyên tắc trong trường hợp này là gì?
Bạn có thể chia sẻ phần thân phương thức cho GetUserNameAndPassword (actionContext, out username, out password) không? –
@VijayBalkawade - Mã này hiện là một phần của dự án nguồn mở SimpleSecurity. Bạn có thể lấy mã nguồn hoàn chỉnh cho GetUserNameAndPassword tại đây. https://simplesecurity.codeplex.com/SourceControl/latest#SimpleSecurity.Filters/BasicAuthorizeAttribute.cs –
Vì Codeplex sắp ngừng hoạt động, tôi đã [sao chép 'GetUserNameAndPassword' vào một Pastebin] (https://pastebin.com/Yq86aNjL). –