2014-08-27 2 views
2

Я передаю returnUrl = Request.Url в действие контроллера, проблема в том, что когда я проверяю его с помощью следующего кода перед перенаправлением, он не работает из-за вызова IsLocalUrl(). Зачем?returnUrl и IsLocalUrl()

if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") 
    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) 
    { 
     return Redirect(returnUrl); 
    } 

Thanks.

+0

Это не так, как в случае с возвратом false? Может быть, это связано с этим вопросом SO: http://stackoverflow.com/questions/8633782/why-does-url-islocalurl-return-false-if-the-url-contains-a-fragment? – Tallmaris

+0

Да, и URL-адрес абсолютно прав: 'http: // localhost: 55058/Orders/Details/102064'. Что именно означает «местный» в этом контексте? – abenci

+0

Глядя на реализацию 'IsReturnUrl' (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.WebPages/RequestExtensions.cs), он, кажется, рассматривает локальные только те вещи, которые начинаются с'/'и '~ /' (но не '//' или '/ \'. Вероятно, вы должны урезать протокол: доменная часть url ... – Tallmaris

ответ

6

Проблема заключалась в том, что просто Url.IsLocalUrl() возвращает истину URL-адреса, как /Orders/Details/5326 и ложные для URL-адресов, как http://www.company.com/Orders/Details/5326

3

Как сказал Альберто, Url.IsLocalUrl() изменился с MVC3 и теперь возвращает истину только тогда, когда путь является относительным. Это реализация в MVC5:

return !url.IsEmpty() && 
     ((url[0] == '/' && (url.Length == 1 || (url[1] != '/' && url[1] != '\\'))) || // "/" or "/foo" but not "//" or "/\" 
     (url.Length > 1 && url[0] == '~' && url[1] == '/')); // "~/" or "~/foo" 

Чтобы обойти эту проблему, вы должны извлечь абсолютный путь из URL вашего, и вы можете сделать это следующим образом:

var returnPath = new Uri(returnUrl).AbsolutePath; 

Тогда вы можете просто использовать в вашем коде, так как все остальные случаи, которые у вас есть, покрыты IsLocalUrl():

if (Url.IsLocalUrl(returnPath)) 
{ 
    return Redirect(returnUrl); 
} 
+3

Это выглядит на 100% неправильно. Документация для Uri.AbsolutePath (https://msdn.microsoft.com/en-us/library/system.uri.absolutepath(v=vs.110) .aspx) говорит: «Информация о пути не включает схему, имя узла или часть запроса в URI». Это означает, что с помощью Uri.AbsolutePath в вашем чеке вы в значительной степени гарантируете, что Url.IsLocalUrl возвращает true независимо от имени хоста. Например, абсолютный путь для http://maliciouswebsite.com/legitimatePath - это «/ legalimatePath», для которого Url.IsLocalUrl вернет значение true. – Bochu

+0

Этот ответ глупо. – nashwan

Смежные вопросы