ASP.NET MVC: атрибут OutputCache игнорирует атрибут RequireHttps? - PullRequest
3 голосов
/ 08 апреля 2011

У меня есть приложение ASP.NET MVC 3 с действием, которое использует атрибуты RequireHttps и OutputCache:

[RequireHttps]
[OutputCache(Duration = 14400, VaryByCustom = "CurrentUser"]
public ActionResult VersionB()
{
  return View();
}

Когда я перехожу на эту страницу, меня перенаправляют на HTTPS,как и ожидалось.

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

Похоже, что OutputCache игнорирует HTTPS, что обеспечивает небезопасный доступ к странице.Можно ли даже кэшировать действие, которое обслуживается по HTTPS?

1 Ответ

10 голосов
/ 09 апреля 2011

Реализация атрибута [RequireHttps] имеет недостатки и не учитывает кэширование.

Вот исправление:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class MyRequireHttpsAttribute : RequireHttpsAttribute
{
    protected virtual bool AuthorizeCore(HttpContextBase httpContext)
    {
        return httpContext.Request.IsSecureConnection;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!AuthorizeCore(filterContext.HttpContext))
        {
            this.HandleNonHttpsRequest(filterContext);
        }
        else
        {
            var cache = filterContext.HttpContext.Response.Cache;
            cache.SetProxyMaxAge(new TimeSpan(0L));
            cache.AddValidationCallback(this.CacheValidateHandler, null);
        }
    }

    private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
    {
        validationStatus = this.OnCacheAuthorization(new HttpContextWrapper(context));
    }

    protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
    {
        if (!AuthorizeCore(httpContext))
        {
            return HttpValidationStatus.IgnoreThisRequest;
        }
        return HttpValidationStatus.Valid;
    }
}

и затем:

[MyRequireHttps]
[OutputCache(Duration = 14400, VaryByCustom = "CurrentUser"]
public ActionResult VersionB()
{
    return View();
}
...