2009-05-15 37 views
5

Khi xây dựng hệ thống quản lý nội dung kết hợp jquery ajax vào GUI của nó, tôi đã gặp phải một trở ngại. Dường như một số khách hàng dành quá nhiều thời gian để suy nghĩ về những gì họ sẽ viết và do đó phiên máy chủ ghi lại chúng, tự nhiên là trang web mà họ không có ý tưởng về điều này. Khi họ cố gắng gửi các thay đổi, tôi sử dụng cuộc gọi ajax đến máy chủ để lưu dữ liệu.Kiểm tra ủy quyền http bằng mvc trước khi gửi biểu mẫu ajax

Điều tôi mong đợi sẽ xảy ra tiếp theo là ứng dụng máy chủ MVC sẽ trả lại trạng thái "401 trái phép". Sau đó tôi có thể nhận được đối tượng jquery ajax của mình để yêu cầu người dùng đăng nhập và sau đó gửi lại các thay đổi khi người dùng được ủy quyền.

Tuy nhiên, những gì thực sự được trả lại từ ứng dụng MVC là trạng thái "302 Đã tìm thấy" và URL chuyển hướng đến trang biểu mẫu đăng nhập của tôi. Trang biểu mẫu đăng nhập trả về mã trạng thái "200 OK" và đối tượng jquery ajax gọi sự kiện thành công cho người dùng biết mọi thứ đã thành công vì đó là ứng dụng MVC đang nói gì.

Có cách nào để tôi có thể áp dụng ứng dụng MVC theo cách tôi nghĩ hay tôi phải sửa đổi các sự kiện jquery ajax để phát hiện trang đăng nhập?

Cập nhật:

Tôi đã sử dụng phản xạ để có một cái nhìn trong mã MVC và thuộc tính phép, trả lại một NotAuthorizedResult mã cho đó là bên dưới (0x191 = 401)

public override void ExecuteResult(ControllerContext context) 
{ 
    if (context == null) 
    { 
     throw new ArgumentNullException("context"); 
    } 
    context.HttpContext.Response.StatusCode = 0x191; 
} 

Tôi nghĩ rằng có thể HttpModule ủy quyền biểu mẫu đang xem 401 và buộc chuyển hướng.

Trả lời

6

bạn có thể thử một cái gì đó như thế này:

void context_EndRequest(object sender, EventArgs e) 
    { 
     var app = sender as HttpApplication; 
     var response = app.Response; 
     var request = app.Request; 

     if ((response.StatusCode == 302) && IsAjaxRequest(request)) 
      response.StatusCode = 401; 
    } 

trong một HttpModule, nó sẽ được sau khi module FormsAuth theo thứ tự như vậy sẽ sửa mã trạng thái. Không đẹp nhưng hiệu quả.

+0

Trong .Net 4.0 (có thể là các phiên bản khác nữa, tôi không biết), FormsAuthentication thực hiện chuyển hướng trong trình xử lý EndRequest.Tôi thấy rằng FormsAuth đã không xử lý các phản ứng nếu tôi sử dụng EndRequest, nhưng bằng cách sử dụng sự kiện PreSendRequestHeaders làm việc tốt hơn rất nhiều (đến sau EndRequest). Cảm ơn bài đăng tuyệt vời này. – womp

5

Tôi thực sự thích giải pháp này. Bằng cách thay đổi đáp ứng 302 trên yêu cầu ajax thành 401, nó cho phép bạn thiết lập ajax ở phía máy khách để theo dõi bất kỳ yêu cầu ajax nào tìm kiếm 401 và nếu nó tìm thấy một chuyển hướng đến trang đăng nhập. Rất đơn giản và hiệu quả.

Global.asax:

protected void Application_EndRequest() 
{ 
    if (Context.Response.StatusCode == 302 && 
     Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest") 
    { 
     Context.Response.Clear(); 
     Context.Response.StatusCode = 401; 
    } 
} 

Client Side Code:

$(function() { 
     $.ajaxSetup({ 
     statusCode: { 
      401: function() { 
      location.href = '/Logon.aspx?ReturnUrl=' + location.pathname; 
      } 
     } 
     }); 
    }); 
1

tôi đã tìm thấy rằng một cách tiếp cận nhẹ hơn chỉ đơn giản là thêm một tiêu đề HTTP tùy chỉnh đến trang đăng nhập và sau đó kiểm tra cho sự hiện diện của điều đó trong lời gọi thành công AJAX.

Tức là. trong LoginController (đây là một dự án MVC, nhưng cùng một nguyên tắc nên áp dụng cho các giải pháp ASP.NET khác):

public ActionResult Login(string returnUrl = "") 
{ 
    Response.AddHeader("X-Unauthorized", "true"); 
    ... 

Và sau đó trong client-side AJAX handler:

success: function(data, textStatus, jqXhr) 
{ 
    if (jqXhr.getResponseHeader("X-Unauthorized")) 
    { 
     ... 

tác phẩm này Cho tôi ít nhất.

Các vấn đề liên quan