2010-01-25 22 views
5

Tôi có một ứng dụng MVC sử dụng [Ủy quyền] để bảo vệ các bit riêng tư. Khi tôi chọn SignOut() URL nó ký cho tôi nhưng nếu tôi nhấn nút quay lại trên trình duyệt của tôi thì nó sẽ chuyển đến trang bảo mật và thậm chí cho phép tôi sử dụng biểu mẫu. Hành động diễn ra và sau đó nó cho thấy rằng tôi đã đăng xuất. Vấn đề là nó thực hiện hành động bảo mật (chèn một hàng vào cơ sở dữ liệu của tôi). Sau đó, tôi có thể sử dụng nút quay lại và thực hiện tất cả. Nếu tôi sử dụng nút quay lại sau khi đăng xuất và nhấn làm mới trình duyệt, nó sẽ hiển thị tôi đã đăng xuất và từ chối truy cập vào trang bảo mật.Sử dụng nút quay lại của trình duyệt sau khi SignOut() cho phép truy cập vào trang bảo mật (ASP.NET MVC)

Tôi có thiếu cái gì quan trọng không? Dường như nó có thể là một vấn đề an ninh thực sự lớn.

public ActionResult LogOff(string ReturnUrl) 
{ 

    FormsAuth.SignOut(); 

    if (!String.IsNullOrEmpty(ReturnUrl)) 
    { 
     return Redirect(ReturnUrl); 
    } 
    else 
    { 

    return RedirectToAction("Index", "Page"); 
    } 
} 
+4

Bạn quên quên [Ủy quyền] xung quanh hành động chấp nhận bài đăng (ở trên [AcceptVerbs (HttpVerbs.Post)]? – Langdon

+0

Không nhưng khi tôi quay trở lại để có một cái nhìn tôi đã có nó như thế này: \t \t [AcceptVerbs (HttpVerbs.Get)] \t \t [Authorize (Roles = "Administrator")] và \t \t [AcceptVerbs (HttpVerbs .Post)] \t \t [Ủy quyền (Vai trò = "Quản trị viên")] Khi tôi đặt cờ Ủy quyền trước AcceptVerbs cho cả Nhận và Đăng nó vẫn cho phép tôi quay lại biểu mẫu nhưng nó sẽ không cho phép tôi đăng . – mark123

+0

Tôi vẫn muốn nó không hiển thị biểu mẫu an toàn cho dù nó cho phép nó đăng lại hay không. Đây là một vấn đề kỳ lạ. Sử dụng trang trí [Ủy quyền] Tôi không cần phải thử nghiệm cho IsAuthenticated, phải không? \t \t \t nếu (! User.Identity.IsAuthenticated) {return RedirectToAction ("LogOn", "Account");} – mark123

Trả lời

5

Tôi nghĩ rằng vấn đề là trình duyệt lưu trữ trang. Đó là lý do tại sao nó không tải lại trang sau khi bạn nhấp vào nút quay lại. Nếu bạn chỉ định trong tiêu đề rằng trang không được lưu trong bộ nhớ cache, nó sẽ tải lại trang sau khi nhấn nút quay lại. Và sau đó người dùng bị từ chối.

Tuy nhiên, để làm cho nó hoạt động có thể phức tạp trong một số trường hợp. Xem số Caching Tutorial để biết thêm thông tin.

1

Bạn có đang sử dụng bất kỳ thông tin phiên nào không? FormsAuth.SignOut() chỉ ảnh hưởng đến các phiên bản mới của trang. Khi bạn quay trở lại, bạn được phép ở đó (trước đây). PostBack được cho phép trừ khi bạn có mã kiểm tra cookie/phiên/tính xác thực của yêu cầu. Nó thậm chí bỏ qua global.asax vì ViewState đã được tạo ra.

Bạn có thể muốn thêm câu lệnh giết phiên hoặc cung cấp một số kiểm tra xác thực bổ sung trong lớp cơ sở của mình để đảm bảo rằng người dùng thực sự được ủy quyền là nơi họ ở, KHI họ đang ở.

Ngoài ra, bạn có thể tắt tính năng lưu vào bộ nhớ đệm trang sẽ khiến nút quay trở lại khá vô dụng (nó sẽ cung cấp trang hết hạn mặc định). Điều này sẽ tạo ra sự kỳ quặc cho những người dùng dựa vào nút quay lại, nhưng nó sẽ giúp đảm bảo tính bảo mật của trang vì nó sẽ buộc một "re-render" của trang ở nơi đầu tiên.

+0

Anh ấy đang sử dụng MVC, do đó, postbacks và viewstates không phải là một vấn đề. Tuy nhiên, việc sử dụng 'Session.Abandon()' trên điều khiển đăng xuất là một ý tưởng hay. –

+0

Tôi không sử dụng Thông tin phiên trong trường hợp này. – mark123

3

Xóa phiên có thể hữu ích. đây là phương pháp đăng xuất của tôi:

public ActionResult Signout() 
    { 
     Session.Clear(); 
     FormsAuthentication.SignOut(); 
     return RedirectToAction("Index", "Home"); 
    } 
1

này là đến cuối câu trả lời, nhưng tôi hy vọng sẽ giúp mọi người trong một thời gian trong Global.asax thêm phương pháp này

protected void Application_BeginRequest() 
{ 
    Response.Cache.SetCacheability(HttpCacheability.NoCache); 
    Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1)); 
    Response.Cache.SetNoStore(); 
} 

và sau đó sau khi hành động chính thêm việc kiểm tra này

if (Request.IsAuthenticated) 
{ 
    // do something 
} 
else 
{ 
    return RedirectToAction("LoginPage", "ControllerName"); 
} 

(hành động chính có nghĩa là bất kỳ hành động [httpget]) và nó sẽ làm việc rất nhiều tôi hy vọng sẽ giúp

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