Получите оригинальный URL-адрес без нестандартного порта (С#)
Первый вопрос!
Окружающая среда
MVC, С#, AppHarbor.
Проблема
Я звоню поставщику openid и создаю абсолютный URL-адрес обратного вызова на основе домена.
На моей локальной машине это отлично работает, если я ударил http://localhost:12345/login
Request.Url; //gives me `http://localhost:12345/callback`
Однако, в AppHarbor, где я развертываю, потому что они используют нестандартные порты, даже если я нажимаю его на " http://sub.example.com/login"
Request.Url; //gives me http://sub.example.com:15232/callback
И это задевает мой обратный вызов, потому что номер порта не был в исходном URL-адресе!
Я пробовал
- Request.Url
- Request.Url.OriginalString
- Request.RawUrl
Все дает мне " http://sub.example.com:15232/callback".
Также, чтобы прояснить, что это не проблема Realm, сообщение об ошибке, которое я получаю от DotNetOpenAuth,
'http://sub.example.com:14107/accounts/openidcallback' not under realm 'http://*.example.com/'.
Я не думаю, что я набил это?
Теперь я собираюсь рассмотреть некоторые хакеры вроде
- команды препроцессора (#IF DEBUG THEN PUT PORT)
- string replace (Request.URL.Contains( "localhost" ))
Все это не 100% -ные решения, но мне надоело размышлять над тем, что может быть простой собственностью, которой я не хватает. Я также прочитал этот, но, похоже, не имеет принятого ответа (и больше касается пути, а не авторитета). Поэтому я отношусь к вам, ребята.
Резюме
Итак, если у меня есть http://localhost:12345/login
, мне нужно получить http://localhost:12345/callback
из контекста Request.
И если бы у меня было http://sub.example.com/login", я должен получить " http://sub.example.com/callback", независимо от того, в каком порту он находится.
Спасибо! (Время сна, ответит на любые вопросы утром)
Ответы
Ответ 1
Это обычная проблема в настройках балансировки нагрузки, таких как AppHarbor - мы предложили пример обхода.
Обновление. Более желательным решением для многих приложений ASP.NET может быть установка aspnet:UseHostHeaderForRequestUrl
appSetting на true
. Мы (AppHarbor) видели, как несколько клиентов испытывают проблемы с использованием своих приложений WCF, поэтому мы не включили его по умолчанию и рекомендуем рекомендовать вышеупомянутое решение для этих ситуаций. Вы можете настроить его с помощью AppHarbor "Конфигурационные переменные", чтобы внедрить настройки приложения при развертывании. Более подробную информацию можно найти в в этой статье.
Ответ 2
Недавно я столкнулся с проблемой, когда сопоставил URL-адрес с текущим URL-адресом, а затем подсвечил навигацию на основе этого. Он работал локально, но не в производстве.
У меня был http://example.com/path/to/file.aspx
как мой файл, но при просмотре этого файла и запуске Request.Url.ToString()
он произвел https://example.com:81/path/to/file.aspx
в рабочей среде с балансировкой нагрузки.
Теперь я использую Request.Url.AbsolutePath
, чтобы просто дать мне /path/to/file.aspx
, таким образом, игнорируя номера схемы, имени хоста и номера порта.
Когда мне нужно сравнить его с URL-адресом для каждого элемента навигации, который я использовал:
New Uri(theLink.Href).AbsolutePath
Ответ 3
Мои первоначальные мысли получают переменную referrer и проверяют, включает ли это порт, если это так использовать, иначе нет.
Если это не опция, потому что прокси-сервер может удалить переменную заголовка referrer, вам может потребоваться использовать некоторую клиентскую сторону script, чтобы получить местоположение и передать его обратно на сервер.
Я предполагаю, что AppHarbor использует переадресацию портов на сервер IIS, поэтому, хотя публично сайт находится на порту 80, IIS размещает его на другом порту, поэтому он не может знать, к какому порту подключен клиент.
Ответ 4
Что-то вроде
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");
Ответ 5
Если вы используете класс UrlBuilder в рамках, вы можете легко обойти это. В классе строителя, если вы установили порт в -1, номер порта будет удален:
new UriBuilder("http://sub.example.com:15232/callback"){ Port = -1}
возвращает: http://sub.example.com/callback
Чтобы сохранить номер порта на локальной машине, просто проверьте Request.IsLocal и не применяйте -1 к порту.
Я бы обернул это в метод расширения, чтобы он был чистым.
Ответ 6
Я вижу, что это старый поток. У меня была проблема с MVC5, на IIS 7.5, с прокси-сервером Apache. Вне сервера я получаю "Empty Response", так как приложение asp.net получает Url из apache с настраиваемым портом.
Чтобы перенаправить приложение в подпути, не включая "настраиваемый" порт, забудьте объекты "Ответ/запрос" и используйте метод "Передача". Например, если я хочу, чтобы пользователи автоматически перенаправлялись на страницу входа в систему, если они уже не вошли в систему:
if (!User.Identity.IsAuthenticated)
Server.TransferRequest("Account/Login");