Использование ASP.NET MVC OutputCache при изменении содержимого View в зависимости от того, прошел ли пользователь проверку подлинности

Я создаю сайт ASP.NET MVC 2, где активно использую параметр OutputCache. Однако у меня есть опасения: использование такого кеширования может помешать аутентификации.

На всех своих страницах я показываю, вошел ли пользователь в систему или нет. Кроме того, в некоторых моих представлениях я выполняю фильтрацию на основе роли пользователя, чтобы определить, отображать ли некоторый контент страницы (например, ссылка Редактировать на одной из моих страниц отображается только для пользователей в роли модератора или администратора).

Повлияет ли использование OutputCache на это динамическое изменение моих представлений? Если да, то как решить эту проблему, не отключая кэширование?


person Maxim Zaslavsky    schedule 09.08.2010    source источник


Ответы (2)


Атрибуты [OutputCache] и [Authorize] хорошо взаимодействуют друг с другом. Метод AuthorizeAttribute.OnAuthorization() устанавливает ловушку в системе кэширования вывода, которая заставляет фильтр авторизации повторно запускаться до того, как страница будет обслуживаться из кэша. Если логика фильтра авторизации дает сбой, это будет рассматриваться как промах кэша. Если логика авторизации прошла успешно, страница будет обслуживаться из кеша. Таким образом, если у вас есть [Authorize(Roles = "Moderator, Administrator")] и [OutputCache] для действия, страница не будет обслуживаться из кеша, если только текущий пользователь не находится в роли модератора или администратора.

Обратите внимание, что это не зависит от пользователя или роли; это буквально повторное выполнение исходной проверки. Представьте, что пользователь А (который является модератором) входит и вызывает кеширование страницы. Теперь пользователь B (который является администратором) входит и открывает кэшированную страницу. Проверка [Авторизация] завершится успешно, так как разрешены и Администратор, и Модератор, а ответ, отправленный пользователю Б, будет содержать точно такое же содержание, что и ответ, отправленный пользователю А.

Обратите внимание, что подстановка ответа не работает в MVC 2. Если вы обслуживаете потенциально конфиденциальные данные, лучше всего не кэшировать их. Если вам абсолютно необходимо кэшировать, вы можете имитировать что-то похожее на подстановку ответов, используя обратный вызов AJAX для динамического заполнения недостающих данных.

person Levi    schedule 09.08.2010
comment
Что, если у меня есть метод, который не требует авторизации, но добавляет ссылку «Редактировать» внутри представления, если пользователь является модератором? В этом случае я пытаюсь сделать что-то похожее на то, как работают кнопки ссылки, флага, редактирования и другие под вопросом или ответом здесь - разве ТАК тоже не использует OutputCache? Спасибо за Ваш ответ! - person Maxim Zaslavsky; 10.08.2010
comment
Я только что наткнулся на blog.stevensanderson.com /2008/10/15/ (о старой проблеме, которая позже была исправлена), что навело меня на мысль - если с OutputCache так плохо с этим, можно ли создать собственный атрибут/фильтр кэширования , который создает разные копии в зависимости от того, вошел ли пользователь в систему и в каких ролях он находится, или, что еще лучше, от имени пользователя, так как я собираюсь написать имя пользователя вверху страница - это возможно? - person Maxim Zaslavsky; 10.08.2010
comment
Как правило, кэширование для каждого пользователя — плохая идея, так как ваш кеш будет переполнен записями. Если кольцевое кэширование важно для вашего сценария, вы также можете использовать фильтр ответов. В начале запроса установите фильтр, который понимает некоторые [!! ПОДСТАВКА ДАННЫХ !!], пусть ваш WriteSubstitute() запишет этот шаблон в поток ответов, а затем в конце запроса ваш фильтр вызовет фактический метод Response.WriteSubstitution(). - person Levi; 10.08.2010
comment
Чтобы ответить на ваш вопрос, связанный с изменением практически любых параметров (включая имя пользователя), см. aspadvice.com/blogs/ssmith/archive/2007/10/29/ и msdn.microsoft.com/en-us/library/. Помните, однако, что это не рекомендуется. - person Levi; 10.08.2010
comment
В итоге я полностью отказался от кэширования для аутентифицированных пользователей по совету Джеффа Этвуда на странице meta.stackexchange.com/questions/60403/ - person Maxim Zaslavsky; 12.08.2010

Я считаю, что вам нужно кэширование донанта ASP.NET. См. здесь для хорошее объяснение. Я не удивлюсь, если SO использует что-то подобное для области верхней панели.

person madcapnmckay    schedule 09.08.2010
comment
Частичное кэширование снова доступно в MVC 3! Уот! - person madcapnmckay; 14.01.2011