Windows Azure ASP.NET MVC Роль ведет себя странно при перенаправлении с HTTP на HTTPS
Subj. У меня есть приложение ASP.NET 2 MVC Worker Role, которое не сильно отличается от шаблона по умолчанию.
При попытке перенаправить с HTTP на HTTPS (это происходит, когда мы обращаемся к контроллеру, защищенному обычной реализацией атрибута RequireSSL), мы получаем пустую страницу с сообщением "Bad Request".
IntelliTrace показывает это:
Брошено: "Файл '/Views/Home/LogOnUserControl.aspx' не существует". (System.Web.HttpException)
Стек вызовов действительно короткий:
[External Code]
App_Web_vfahw7gz.dll!ASP.views_shared_site_master.__Render__control1(System.Web.UI.HtmlTextWriter __w = {unknown}, System.Web.UI.Control parameterContainer = {unknown})
[External Code]
App_Web_bsbqxr44.dll!ASP.views_home_index_aspx.ProcessRequest(System.Web.HttpContext context = {unknown})
[External Code]
Ссылка на пользовательский элемент управления является обычной в /Views/Shared/Site.Master:
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
И частичное представление LogOnUserControl.ashx находится в Views/Shared (и это ASCX, а не ASPX).
Проблема обнаруживается, когда мы пытаемся получить доступ к страницам сайта, которые требуют авторизации (FormsAuth) и перенаправления из-за SSL. Эти страницы защищены атрибутом RequireSSL (Redirect == true):
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class RequireSslAttribute : FilterAttribute, IAuthorizationFilter
{
public bool Redirect { get; set; }
// Methods
public void OnAuthorization(AuthorizationContext filterContext)
{
// this get's messy, when we are running custom ports
// within the local dev fabric.
// hence we disable code in the debug
#if !DEBUG
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (filterContext.HttpContext.Request.IsSecureConnection)
return;
var canRedirect = string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase);
if (canRedirect && Redirect)
{
var builder = new UriBuilder
{
Scheme = "https",
Host = filterContext.HttpContext.Request.Url.Host,
Path = filterContext.HttpContext.Request.RawUrl
};
filterContext.Result = new RedirectResult(builder.ToString());
}
else
{
throw new HttpException(0x193, "Access forbidden. The requested resource requires an SSL connection.");
}
#endif
}
}
Очевидно, мы компилируем в RELEASE для этого случая.
У кого-нибудь есть идеи, что может вызвать это странное исключение и как от него избавиться?
2 ответа
Есть ли конкретная причина, по которой ваше частичное представление "LogOnUserControl" является файлом ashx, а не aspx/ascx? У меня сложилось впечатление, что MVC ищет только файлы.aspx и.ascx в качестве соглашения.
NB: это не правильное решение, но пока оно работает. Помечая весь домашний контроллер с помощью RequireSsl, мы заставляем всех посетителей использовать Https с самого начала.
По-прежнему возможно вызвать ошибку, вызвав что-то вроде:
http://project.company.com/User/Login?ReturnUrl=/solution
Но вряд ли вы попадете по такой ссылке, перейдя по сайту, так что пока это будет работать.