Требуемый токен против подделки не был предоставлен или был недействительным - PullRequest
9 голосов
/ 21 декабря 2011

Я использую MVC 3 и все настроено правильно, как я вижу.

Пользователь Authenticates отправляет форму с токеном AntiForgery, и все работает нормально.

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

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

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

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

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

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

Это проблема внутри самого MVC?

Настройки машинного ключа и все в порядке, поэтому проблема не возникает.

Ответы [ 3 ]

5 голосов
/ 12 июля 2012

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

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

Примечание. Чтобы устранить эту ошибку, также важно создать машинный ключ.

Google: генератор ключей машин

3 голосов
/ 13 апреля 2014

Я добавляю лучший ответ, потому что это такая боль и плохо отвечает по всему Интернету. Я подумал, что добавлю свои текущие рабочие решения.

Принципиально (игнорируя различные опции) AntiForgeryToken работаетпутем добавления файла cookie сеанса, который затем читается при публикации формы, путем украшения контроллера с помощью атрибута [ValidateAntiForgeryToken].

Прежде чем приступить к исправлению чего-либо в качестве общего правила, всегда выполните следующее.

  1. В web.config создайте ключ machineKey следующим образом.

    <machineKey validationKey="YOUR_KEY" decryptionKey="YOUR_KEY" validation="SHA1" decryption="AES" />

    ** Обратите внимание, что SHA1 на самом деле уже не очень безопасен, но это другое обсуждение**

    Google <machineKey> Generator и настройте.

    http://msdn.microsoft.com/en-us/library/w8h3skw9%28v=vs.100%29.aspx

  2. Измените имя файла cookie по умолчанию с __RequestVerificationToken на имя, которое не будет использоватьсядругое приложение.(Я всегда использую GUID).

    Сделайте это с AntiForgeryConfig.CookieName = "YOUR_NAME";

  3. Создайте новый пользовательский атрибут.

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

Другая проблема заключается в том, что если у вас есть атрибут [Authorize] в опубликованном контроллере, поток вещей вызовет исключение HttpAntiForgeryException, прежде чем он проверит, кто аутентифицирован.(в большинстве аутентификаций на основе файлов cookie, когда сеанс истек, пользователь больше не проходит аутентификацию)

Способ решить эту проблему - создать собственный атрибут [CustomValidateAntiForgeryToken].

[AttributeUsage( AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
  public class CustomValidateAntiForgeryToken : FilterAttribute, IAuthorizationFilter {

    public void OnAuthorization( AuthorizationContext filterContext ) {

      if ( filterContext == null ) {
        throw new ArgumentNullException( "filterContext" );
      }

      try {
        AntiForgery.Validate();
      }
      catch {

        // Here do whatever is you wish 
        // you could just re throw the error or what ever.

        // In this case I have redirected to a Signout

        filterContext.Result = new RedirectToRouteResult( 
          new RouteValueDictionary( 
            new {
              action     = "Sign_Out",
              controller = "SOME_CONTROLLER",
              area       = ""
            } 
          )
        );

      }

    }

  }

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

Очевидно, что у людей совершенно разные потребности, но, надеюсь, это дает достаточно советов для управления этой очень распространенной и раздражающей проблемой.

Если кто-нибудь увидит что-нибудь, что поможет или может быть добавлено, пожалуйста, сделайте.

1 голос
/ 21 декабря 2011

В вашем действии поместите атрибут [Authorize] выше атрибута [ValidateAntiForgeryToken]. Они выполняются в порядке сверху вниз. Таким образом, он должен нажать на разрешение и увидеть, что вы больше не аутентифицированы.

...