Подтвердить что ты не робот

Кнопка "Назад" и токен анти-подделки

Я получаю Runtime error связанный атрибут анти-подделки.

Выполните следующие шаги:

Ошибка: The provided anti-forgery token was meant for a different claims-based user than the current user.

Что можно сделать, чтобы предотвратить эту ошибку?

4b9b3361

Ответ 1

Это один из способов игнорировать ошибку и возвращать пользователя на экран входа в систему. Это просто пример.

Создайте новый класс с именем HandleAntiforgeryTokenErrorAttribute, который наследуется от HandleErrorAttribute. Переопределите метод OnException.

public class HandleAntiforgeryTokenErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;
        filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary(new { action = "Login", controller = "Account" }));
    }
}

Перейдите в свой FilterConfig класс и зарегистрируйте атрибут как глобальный фильтр.

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new HandleAntiforgeryTokenErrorAttribute()
            { ExceptionType = typeof(HttpAntiForgeryException) }
        );
    }
}

Ответ 2

У меня была такая же проблема только сейчас, и я решил ее отключить кэширование входа в систему. Это на самом деле имеет большой смысл и не требует обработки кода или исключений.

Теперь мой метод управления журналом выглядит следующим образом:

[AllowAnonymous]
[OutputCache(NoStore = true, Location = OutputCacheLocation.None)]
public ActionResult LogOn(Uri returnUrl)

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

Я считаю, что это намного более чистый, простой и логичный подход к проблеме.

Ответ 3

Кэшированные старые страницы, возвращенные к жизни с помощью кнопки "назад", содержат старые антиблокировочные жетоны и вызывают исключение. Решение глобального фильтра от Rowan Freeman перенаправляется на страницу входа в систему. Однако эта проблема кэширования также заставляет сайт обслуживать старую страницу входа со старым токеном. Отправка формы приведет к тому же исключению. Ergo, IMO, должны быть реализованы оба решения (решения Rowan Freeman и julealgon).

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

Ответ 4

Принятые ответы просто улавливают все исключения, потому что они не фильтруют их по типу исключений, как это делает оригинальный HandleErrorAttribute.

Используйте следующий код, чтобы обрабатывать только HttpAntiForgeryException:

public static class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new HandleAntiforgeryTokenErrorAttribute());
    }
}

public class HandleAntiforgeryTokenErrorAttribute : HandleErrorAttribute
{
    public HandleAntiforgeryTokenErrorAttribute()
    {
        ExceptionType = typeof(HttpAntiForgeryException);
    }

    public override void OnException(ExceptionContext filterContext)
    {
        if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
        {
            return;
        }

        filterContext.ExceptionHandled = true;
        filterContext.Result =
            new RedirectToRouteResult(
                new RouteValueDictionary(
                    new {
                            area = string.Empty,
                            action = "Index",
                            controller = "Home"
                        }));

    }
}