ReturnUrl в ASP.NET MVC - PullRequest
       33

ReturnUrl в ASP.NET MVC

30 голосов
/ 22 апреля 2009

У меня сейчас есть ссылка для входа в мое приложение, которое выглядит примерно так:

<a href="/login?ReturnUrl=" + <%= Request.RawUrl %>>Login</a>

Я хочу обработать команду POST на странице входа в действие контроллера ниже:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Login(string returnUrl)
{
    // Authenticate user

    return Redirect(returnUrl);
}

Проблема здесь в том, что если RawUrl имеет что-то с несколькими параметрами url, такими как «somepage? Param1 = 1 & param2 = 2 & param3 = 3», то returnUrl, который передается в действие Login, усекается после первого амперсанда: «somepage? Param1 = 1" .

Я пробовал UrlEncoding в RawUrl, но, похоже, это что-то меняет. Похоже, что инфраструктура ASP.NET MVC здесь - это UrlDecoding для параметров url перед их сопоставлением с параметрами действия контроллера, что в итоге приводит к удалению дополнительных параметров url, которые я хочу видеть в моем параметре returnUrl.

Есть ли способ обойти это? Я знаю, что могу просто использовать Request.Path и разобрать нужные мне значения, но я подумал, что сначала посмотрю, есть ли более чистый подход.

Ответы [ 3 ]

38 голосов
/ 22 апреля 2009

Возможно, вы неправильно кодируете ссылки. Да, они должны быть закодированы. Вот как мы это делаем:

<a href="<%= Url.Action("Delete", "TimeRecord", 
    new RouteValueDictionary(new { id = timeRecord.AltId, 
    returnUrl=ViewContext.HttpContext.Request.Url.PathAndQuery }) ) %>">
8 голосов
/ 22 апреля 2009

Убедитесь, что ваш URL кодирует RawUrl перед его использованием.

<%= Url.Encode(Request.RawUrl) %>

Это должно сделать это для вас.

0 голосов
/ 22 апреля 2009

Хорошо, ваш раствор имеет запах; Я не могу указать на ссылку, описывающую атаку (это должен быть какой-то перехват сеанса), но слепое перенаправление через строку запроса ДОЛЖНО быть дырой в безопасности. Кто-нибудь ответит или прокомментирует информацию, пожалуйста.

Не задумываясь об аспекте безопасности, одним из быстрых решений было бы закодировать Base64 весь возвращаемый URL. Вот код, который я полностью вытащил из блога , который может работать или не работать:

public static string ToBase64(this HtmlHelper me, string toEncode)
{
      byte[] toEncodeAsBytes
            = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
      string returnValue
            = System.Convert.ToBase64String(toEncodeAsBytes);
      return returnValue;
}

public static string FromBase64(this HtmlHelper me, string encodedData)
{
      byte[] encodedDataAsBytes
          = System.Convert.FromBase64String(encodedData);
      string returnValue =
         System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
      return returnValue;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...