Может кто-нибудь объяснить мне этот блок кода ASP.NET MVC, пожалуйста? - PullRequest
5 голосов
/ 06 июня 2010

это текущий код в ASP.NET MVC2 (RTM) System.Web.Mvc.AuthorizeAttribute класс: -

public virtual void OnAuthorization(AuthorizationContext filterContext)
{
    if (filterContext == null)
    {
        throw new ArgumentNullException("filterContext");
    }
    if (this.AuthorizeCore(filterContext.HttpContext))
    {
        HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
        cache.SetProxyMaxAge(new TimeSpan(0L));
        cache.AddValidationCallback(
            new HttpCacheValidateHandler(this.CacheValidateHandler), null);
    }
    else
    {
        filterContext.Result = new HttpUnauthorizedResult();
    }
}

так что, если я «авторизован», тогда делайте некоторые вещи для кэширования, в противном случае выведите 401 несанкционированный ответ.

Вопрос: Что делают эти 3 строки кэширования?

ура:)

Ответы [ 2 ]

15 голосов
/ 07 июня 2010

Этот код существует, чтобы позволить вам одновременно использовать [OutputCache] и [Authorize] для действия без риска кэширования ответа, который был сгенерирован для авторизованного пользователя и передан пользователю, который не авторизован.

Вот комментарий исходного кода от AuthorizeAttribute.cs:

Так как мы выполняем авторизацию на уровне действий, авторизация код запускается после кэширования вывода модуль. В худшем случае это могло разрешить авторизованному пользователю вызывать страница для кэширования, затем неавторизованный пользователь позже будет обслуживал кэшированную страницу. Мы работаем вокруг это говорит прокси не кэшировать чувствительная страница, то мы подключаем пользовательский код авторизации в механизм кэширования, так что мы имеем последнее слово о том, должна ли быть страница подается из кеша.

Так что же делает этот атрибут? Сначала он отключает прокси-кэширование этого ответа, поскольку прокси-серверы не могут правильно определить, какие пользователи имеют или не авторизованы для его просмотра. И если прокси-сервер отправляет ответ неавторизованному пользователю, это очень плохо.

А как насчет AddValidationCallback? В ASP.NET модуль кэширования вывода перехватывает события, которые запускаются до обработчика HTTP. Поскольку MVC на самом деле является просто специальным обработчиком HTTP, это означает, что если модуль кэширования вывода обнаружит, что этот ответ уже был кэширован, то модуль просто будет обслуживать ответ непосредственно из кэша, вообще не проходя через конвейер MVC. Это также может быть очень плохой вещью, если кэш вывода служит ответом неавторизованному пользователю.

Теперь подробнее рассмотрим CacheValidateHandler :

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

// This method must be thread-safe since it is called by the caching module.
protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext) {
    if (httpContext == null) {
        throw new ArgumentNullException("httpContext");
    }

    bool isAuthorized = AuthorizeCore(httpContext);
    return (isAuthorized) ? HttpValidationStatus.Valid : HttpValidationStatus.IgnoreThisRequest;
}

Это фактически просто связывает метод AuthorizeCore с кэшированным ответом. Когда модуль кэша вывода обнаруживает совпадение, он повторно запускает метод AuthorizeCore, чтобы убедиться, что текущему пользователю действительно разрешено видеть кэшированный ответ. Если AuthorizeCore возвращает true, он обрабатывается как попадание в кэш (HttpValidationStatus.Valid), и ответ подается из кэша без прохождения через конвейер MVC. Если AuthorizeCore возвращает значение false, это считается ошибкой кэша (HttpValidationStatus.IgnoreThisRequest), и конвейер MVC работает как обычно, чтобы сгенерировать ответ.

Кроме того, поскольку делегат создается для AuthorizeCore (таким образом, захватывая конкретный экземпляр AuthorizeAttribute) и сохраняется в статическом кэше, именно поэтому все типы подклассов AuthorizeAttribute должны быть поточно-ориентированными.

2 голосов
/ 06 июня 2010

вызов AuthorizeCore будет подтвержден, если запрос будет авторизован. Если санкционировано, это помещает AddValidationCallback для проверки, является ли кэшированный вывод все еще действительным согласно политике кэширования. Если это так, кэшированный вывод отправляется клиенту.

По поводу 3 строк для кеширования; ну, во-первых, вы должны понимать, что кэш вывода должен быть корректным или максимально корректным. Чтобы измерить ее «правильность», система проверит, соответствует ли она определенным условиям (например, она не была изменена). Это можно сделать в 3 строки.

...