2011-10-06 28 views
17

Câu hỏi đầu tiên!Nhận url gốc mà không có cổng không chuẩn (C#)


Môi trường

MVC, C#, AppHarbor.

Vấn đề

tôi kêu gọi một nhà cung cấp OpenID, và tạo ra một địa chỉ gọi lại tuyệt đối dựa trên tên miền.

Trên máy tính địa phương của tôi, điều này hoạt động tốt nếu tôi trúng http://localhost:12345/login

Request.Url; //gives me `http://localhost:12345/callback` 

Tuy nhiên, trên AppHarbor nơi tôi đang triển khai, bởi vì họ đang sử dụng cổng non-standard, ngay cả khi tôi đang đánh nó tại "http://sub.example.com/login"

Request.Url; //gives me http://sub.example.com:15232/callback 

Và điều này vít lên gọi lại của tôi, vì số cổng không có trong url nguồn ban đầu!

Tôi đã thử

  • Request.Url
  • Request.Url.OriginalString
  • Request.RawUrl

Tất cả mang lại cho tôi "http://sub.example.com:15232/callback".

Ngoài ra để làm sáng tỏ rằng đây không phải là một vấn đề Realm, thông báo lỗi tôi nhận được từ DotNetOpenAuth là

'http://sub.example.com:14107/accounts/openidcallback' not under realm 'http://*.example.com/'. 

Tôi không nghĩ rằng tôi đã nhồi mà lên?

Bây giờ, tôi muốn xem xét một số nội dung hacky như

  • lệnh preprocessor (# nếu DEBUG sau đó đặt PORT)
  • chuỗi thay thế (Request.URL.Contains ("localhost"))

Tất cả những điều này không phải là 100% giải pháp, nhưng tôi bị bệnh về việc nghiền ngẫm về những gì có thể là một tài sản đơn giản mà tôi bị thiếu. Tôi cũng đã đọc this nhưng điều đó dường như không có câu trả lời được chấp nhận (và nhiều hơn về đường dẫn thay vì quyền hạn). Vì vậy, tôi đưa nó về phía các bạn.

Tóm tắt

Vì vậy, nếu tôi đã http://localhost:12345/login, tôi cần phải nhận được http://localhost:12345/callback từ bối cảnh yêu cầu.

Và nếu tôi có "http://sub.example.com/login", tôi sẽ nhận được "http://sub.example.com/callback", bất kể cổng đó đang bật.

Cảm ơn!(Thời gian ngủ, sẽ trả lời bất kỳ câu hỏi nào vào buổi sáng)

Trả lời

20

Đây là một vấn đề phổ biến trong các thiết lập cân bằng tải như AppHarbor của - chúng tôi đã cung cấp một example workaround.

Cập nhật: Một giải pháp hấp dẫn hơn cho nhiều ứng dụng ASP.NET có thể là đặt aspnet:UseHostHeaderForRequestUrl appSetting thành true. Chúng tôi (AppHarbor) đã thấy một số khách hàng gặp vấn đề khi sử dụng ứng dụng WCF của họ, đó là lý do tại sao chúng tôi không kích hoạt nó theo mặc định và stil đề xuất giải pháp trên cho những tình huống đó. Bạn có thể cấu hình nó bằng cách sử dụng "Biến cấu hình" của AppHarbor để chèn các ứng dụng khi triển khai. Thông tin thêm có thể được tìm thấy trong this article.

0

Suy nghĩ ban đầu của tôi là nhận biến giới thiệu và kiểm tra xem có bao gồm cổng hay không.

Nếu đó không phải là tùy chọn vì proxy có thể xóa biến tiêu đề liên kết giới thiệu thì bạn có thể cần sử dụng một số tập lệnh phía máy khách để lấy vị trí và truyền lại cho máy chủ. Tôi đoán rằng AppHarbor sử dụng cổng chuyển tiếp đến máy chủ IIS vì vậy mặc dù công khai trang web là trên cổng 80 IIS có nó được lưu trữ trên một cổng để nó không thể biết cổng khách hàng kết nối vào.

+0

Tôi đã kết thúc bằng cách sử dụng UrlReferrer (điều này không có cổng vì một số lý do GRR!) Nhưng bài đã dẫn tôi tới đó. Tôi không ngay lập tức chắc chắn về bất kỳ chi nhánh nào, nhưng cảm ơn anyway :) –

+0

bạn đã thử sử dụng một số javascript để có được cổng? bạn có thể vượt qua nó trong chuỗi truy vấn hoặc đăng lại. – Robert

+0

Đó là khá hacky, không phải cái gì tôi muốn dựa vào. –

0

Something như

String port = Request.ServerVariables["SERVER_PORT"] == "80" ? "" : ":" + Request.ServerVariables["SERVER_PORT"]; 
String virtualRoot = Url.Content("~/"); 
destinationUrl = String.Format("http://{0}{1}{2}", Request.ServerVariables["SERVER_NAME"], port + virtualRoot, "/callback"); 
+0

Thao tác này cũng sẽ xóa cổng trên cá thể cục bộ của tôi. :( –

1

Gần đây, tôi đã gặp sự cố khi tôi so sánh URL với URL hiện tại và sau đó đánh dấu điều hướng dựa trên điều đó. Nó hoạt động cục bộ, nhưng không hoạt động trong sản xuất.

Tôi có http://example.com/path/to/file.aspx làm tệp của mình, nhưng khi xem tệp đó và chạy Request.Url.ToString(), nó tạo ra https://example.com:81/path/to/file.aspx trong môi trường sản xuất cân bằng tải.

Bây giờ tôi đang sử dụng Request.Url.AbsolutePath để chỉ cung cấp cho tôi /path/to/file.aspx, do đó bỏ qua sơ đồ, tên máy chủ và số cổng.

Khi tôi cần phải so sánh nó với URL trên mỗi mục menu tôi đã sử dụng: New Uri(theLink.Href).AbsolutePath

0

Nếu bạn sử dụng lớp UrlBuilder trong khuôn khổ bạn easly có thể làm được việc này. Trên lớp builder nếu bạn thiết lập các cổng đến -1 sau đó số cổng sẽ được gỡ bỏ:

new UriBuilder("http://sub.example.com:15232/callback"){ Port = -1} 

lợi nhuận: http://sub.example.com/callback

Để giữ số cổng trên máy tính cục bộ chỉ cần kiểm tra Request.IsLocal và don Áp dụng -1 cho cổng.

Tôi sẽ áp dụng phương pháp này để làm cho nó sạch sẽ.

0

Tôi thấy rằng đây là một chuỗi cũ. Tôi đã có vấn đề này chạy MVC5, trên IIS 7.5, với một proxy Apache ở phía trước. Bên ngoài máy chủ, tôi sẽ nhận được "Phản hồi trống", vì ứng dụng asp.net nhận được Url từ apache với cổng tùy chỉnh.

Để chuyển ứng dụng sang đường phụ mà không bao gồm cổng "tùy chỉnh", hãy quên đối tượng Response/Request và sử dụng phương thức Chuyển.Ví dụ: nếu tôi muốn người dùng đó được tự động chuyển hướng đến trang đăng nhập trong trường hợp họ chưa đăng nhập:

if (!User.Identity.IsAuthenticated) 
    Server.TransferRequest("Account/Login"); 
Các vấn đề liên quan