Получить оригинальный URL без нестандартного порта (C #) - PullRequest
18 голосов
/ 06 октября 2011

Первый вопрос!


Окружающая среда

MVC, C #, 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 ОТЛАДКА ПОСЛЕ ТОГО, КАК PUT)
  • string replace (Request.URL.Contains ("localhost"))

Все это не 100% -ные решения, но мне надоело размышлять над тем, что может быть простым свойством, которое мне не хватает. Я также прочитал это , но, похоже, на этот вопрос нет принятого ответа (и больше о пути, чем о авторитете). Так что я обращаюсь к вам, ребята.

Резюме

Так что, если у меня было http://localhost:12345/login, мне нужно получить http://localhost:12345/callback из контекста запроса.

И если бы у меня было "http://sub.example.com/login",, я должен получить" http://sub.example.com/callback", независимо от того, к какому порту он подключен.

Спасибо! (Время сна, утром отвечу на любые вопросы)

Ответы [ 6 ]

21 голосов
/ 09 октября 2011

Это распространенная проблема в установках с балансировкой нагрузки, таких как AppHarbor - мы предоставили пример обходного решения .

Обновление. Более желательным решением для многих приложений ASP.NET может быть установка aspnet:UseHostHeaderForRequestUrl appSetting на true.Мы (AppHarbor) видели, что у нескольких клиентов возникали проблемы с его использованием в приложениях WCF, поэтому мы не включили его по умолчанию и все еще рекомендуем вышеуказанное решение для таких ситуаций.Вы можете настроить его, используя «Переменные конфигурации» AppHarbor для внедрения настроек приложения при развертывании.Более подробную информацию можно найти в этой статье .

1 голос
/ 23 мая 2013

Недавно я столкнулся с проблемой, когда сравнивал 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

0 голосов
/ 18 сентября 2015

Я вижу, что это старая тема.У меня была эта проблема при запуске MVC5 на IIS 7.5 с прокси-сервером Apache впереди.За пределами сервера я получил бы «Пустой ответ», так как приложение asp.net получает URL-адрес от apache с настраиваемым портом.

Для того, чтобы приложение перенаправляло на подпуть без включения «настраиваемого»msgstr "порт, забудьте объекты Response / Request и используйте метод Transfer.Например, если я хочу, чтобы пользователи автоматически перенаправлялись на страницу входа, если они еще не зарегистрированы:

if (!User.Identity.IsAuthenticated)   
    Server.TransferRequest("Account/Login");
0 голосов
/ 11 марта 2014

Если вы используете класс UrlBuilder в рамках, вы можете легко обойти это. В классе компоновщика, если вы установите порт -1, номер порта будет удален:

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

возвращает: http://sub.example.com/callback

Чтобы сохранить номер порта на локальном компьютере, просто отметьте Request.IsLocal и не применяйте -1 к порту.

Я бы обернул это в метод расширения, чтобы сохранить его в чистоте.

0 голосов
/ 06 октября 2011

Что-то вроде

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 голосов
/ 06 октября 2011

Мои первые мысли - получить переменную реферера и проверить, включает ли он порт, если это так, используйте его иначе.

Если это не вариант, поскольку прокси-сервер может удалить переменную заголовка referrer, то вам может потребоваться использовать некоторый сценарий на стороне клиента, чтобы получить местоположение и передать его обратно на сервер.

Я предполагаю, что AppHarbor использует переадресацию портов на сервер IIS, поэтому, хотя публично сайт находится на порте 80, IIS размещает его на другом порту, поэтому он не может знать, к какому порту подключен клиент.

...