2008-12-18 45 views
11

Tôi có ứng dụng xác thực trung tâm trên máy chủ a. Máy chủ b có một hoặc nhiều ứng dụng trên cùng một miền cần xác thực từ máy chủ a. Nó đủ dễ dàng để thiết lập nó để các ứng dụng máy chủ b chuyển hướng đến máy chủ a. Không có gì dễ dàng khi nhận được ReturnURL là tuyệt đối.Xác thực biểu mẫu + ASP.NET MVC tuyệt đối ReturnURL

Đây là nếp nhăn. Ứng dụng tiêu thụ trên máy chủ b có hai bộ điều khiển, một công cộng và một bộ điều khiển được bảo mật. Nếu trang trí [ủy quyền] được đặt trên một hành động ở nơi công cộng (là bộ điều khiển mặc định), tôi sẽ nhận được URL tuyệt đối thích hợp. Tuy nhiên, nếu trong bộ điều khiển riêng của nó, tôi nhận được một URL tương đối.

Tôi có thể chặn sự kiện được yêu cầu trước trong các ứng dụng tiêu thụ, nhưng tôi cần một số phần của trang web được công khai, chứ không phải toàn bộ sự cố.

Ý tưởng?

Trả lời

15

Cách thức AuthorizeAttribute chuẩn hoạt động bằng cách đặt mã trạng thái phản hồi thành 401 nếu yêu cầu không được xác thực. Điều này đá trong phản ứng tiêu chuẩn của mô-đun xác thực mặc định cho một yêu cầu trái phép. Tôi cho rằng bạn đang sử dụng xác thực dựa trên biểu mẫu, điều này sẽ tạo url trả về dựa trên url trong yêu cầu. Trong trường hợp này, có thể là một URL tương đối.

Một điều bạn có thể làm là thay vì dựa vào hành vi tích hợp sẵn, bạn có thể triển khai một SSOAuthorizeAttribute mở rộng lớp AuthorizeAttribute và ghi đè OnAuthorization. Sau đó bạn có thể trích xuất loginUrl từ phần tử biểu mẫu trong cấu hình web và xây dựng RedirectResult của riêng bạn và kéo returnUrl từ thuộc tính HttpContext.Request.Url.AbsoluteUri trong tham số AuthorizationContext.

public class SSOAuthorizeAttribute : AuthorizeAttribute 
{ 
     public override void OnAuthorization( 
          AuthorizationContext filterContext) 
     { 
      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
      { 
       // get from cached variable from web configuration 
       string loginUrl = ... 
       if (filterContext.HttpContext.Request != null) 
       { 
        loginUrl += "?ReturnUrl=" + filterContext.HttpContext 
                  .Request 
                  .Url 
                  .AbsoluteUri; 
       } 

       filterContext.Result = new RedirectResult(loginUrl); 
      } 
     } 
} 
+0

cảm ơn cho câu trả lời hữu ích, cho bất cứ ai sử dụng này, lưu ý rằng 'filterContext.Cancel' là không có trong MVC4, bây giờ bạn chỉ cần thiết lập kết quả. – Menahem

+0

@Menahem - Tôi đã xóa dòng không cần thiết. Cảm ơn bạn đã cảnh báo. – tvanfosson

5

Giả sử hình thức xác thực, trong các ứng dụng máy chủ B web.config, thiết lập các thuộc tính loginUrl trên thẻ hình thức đến một phương pháp hành động điều khiển mà đinh trên url tuyệt đối trước khi chuyển hướng đến máy chủ A.

Config trên máy chủ B

<authentication mode="Forms"> 
    <forms loginUrl="/Account/LoginRedirect" /> 
</authentication> 

phương pháp hành động sẽ như thế nào

public RedirectResult LoginRedirect(string returnUrl) 
    { 
     var requestUrl = HttpContext.Current.Request.Url; 
     return LoginUrlOnServerA + 
       "?returnUrl=" +   
       HttpUtility.UrlEncode(string.Format("http://{0}:{1}{2}", 
       requestUrl.Host, 
       requestUrl.Port, 
       HttpUtility.UrlDecode(returnUrl))); 
    } 
0

như https://stackoverflow.com/a/583608/80589 nhưng ngắn:

public RedirectResult LogOn(string returnUrl) 
{ 
    var r = new Uri(Request.Url, returnUrl).ToString(); 
    return Redirect("https://logonserver.com/?return_url=" + Url.Encode(r)); 
} 
Các vấn đề liên quan