Microsoft.IdentityModel: ключ недействителен для использования в указанном состоянии

У меня есть веб-приложение, поддерживающее требования, с использованием Windows Identity Foundation, который работает хорошо, за исключением одного сервера. Я вижу сообщение об ошибке, приведенное ниже в журнале событий.

Exception information: 
    Exception type: CryptographicException 
    Exception message: Key not valid for use in specified state.

   at System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope)
   at Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded)

Это приложение использует очень стандартную реализацию WIF с ADFS v2. Он не использует RsaEncryptionCookieTransform. Я ищу любые предложения о том, как диагностировать это. Вещи, которые я пробовал до сих пор:

  • Пул приложений использует идентификатор ASP.NET v4.0, для которого установлено значение "Загрузить профиль пользователя" равным true.
  • Я удалил папку C:\Users\ASP.NET v4.0\AppData и увидел, что это было успешно воссоздано.
  • Я проверил разрешения на закрытые ключи сертификата, которые были хорошими. Я также попытался отключить шифрование токена, которое не имело никакого значения.

Любые советы будут оценены.

Ответ 1

Это обычно вызвано тем, что приложение не может расшифровать cookie файл маркера аутентификации. Убедитесь, что личность, которой принадлежит пул приложений, имеет достаточные права доступа к хранилищу сертификатов. Попробуйте изменить Identity на NetworkService и посмотрите, помогает ли это.

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

Ответ 2

Проблема на 100% воспроизводима:

Действительно, после повторного развертывания приложения И старый cookie-аутентификация остается на клиентской машине (клиент не выходил) - эта ошибка появляется клиенту по любому следующему запросу. Чтобы исправить эту ошибку, клиент должен удалить файлы cookie и/или зарегистрироваться, а затем выйти из STS. Как только все будет сделано - ошибка исчезнет, ​​и все будет в порядке до следующего обновления....

После некоторых исследований, я думаю, что это ошибка в SessionAuthenticationModule, которая должна быть исправлена. Если вы внимательно посмотрите на трассировку стека выше, есть интересный метод TryReadSessionTokenFromCookie, который устанавливает, что модуль аутентификации "попробует" прочитать токен из файла cookie и вернет false, если это не сработает - это код (благодаря Resharper):

public bool TryReadSessionTokenFromCookie(out SessionSecurityToken sessionToken)
{
    byte[] sessionCookie = this.CookieHandler.Read();
    if (sessionCookie == null)
    {
        sessionToken = null;
        return false;
    }
    sessionToken = this.ReadSessionTokenFromCookie(sessionCookie);
    if (DiagnosticUtil.TraceUtil.ShouldTrace(TraceEventType.Verbose))
    {
        DiagnosticUtil.TraceUtil.Trace(TraceEventType.Verbose, TraceCode.Diagnostics, SR.GetString("TraceValidateToken", new object[0]), new TokenTraceRecord(sessionToken), null);
    }
    return true;
}

Очевидно, что код не работает в этом методе с необработанной ошибкой, и разработчик остается без какой-либо опции для обработки ошибки более или менее разумным способом. (... Или, по крайней мере, я не смог найти, так как этот HTTP-модуль не передает эту ошибку на объект HttpApplication для обработки и бросает его в лицо пользователя.) Итак, я думаю, что есть две ошибки: 1) Обработчик маркера безопасности должен быть более конкретным в рассуждениях об отказе ID1073 (ошибка дешифрования на стороне сервера или неправильная (старая) ошибка cookie) 2) Для разработчика должен быть способ обработать эту ошибку и выйти из системы, если это произойдет. Я возьму ЛЮБОЙ помощи в этом... Может ли кто-нибудь ПОЖАЛУЙСТА создать образец кода, показывающий, как перехватить это исключение, чтобы пользователь мог автоматически выходить из системы при возникновении этой ошибки? Опять же, событие Application.Error, похоже, не запускается из этого модуля - не уверен, что еще можно сделать для его обработки, кроме написания моего собственного SessionAuthenticationModule. ЛЮБАЯ ПОМОЩЬ ВЫСОКО ЦЕНИТСЯ!!! Благодарю! Alex

Ответ 3

Я разрешаю свое дело, потому что у меня есть одно имя cookie "FedAuth" для двух приложений (это имя по умолчанию). Просто введите другое имя и решите:

<system.identityModel.services>
<federationConfiguration>
  <cookieHandler name="ACookieName" />
</federationConfiguration>

Ответ 4

Следующие работали для меня:

Вам нужно добавить раздел в system.identityModel/identityConfiguration

Ссылка: SessionSecurityTokenHandler пытается расшифровать SessionSecurityToken в зашифрованном в RSA файле cookie с использованием DPAPI; почему?

  <system.identityModel>
    <identityConfiguration saveBootstrapContext="true">
      <audienceUris>
        <add value="yoursite.com" />
      </audienceUris>
      <issuerNameRegistry type="Thinktecture.IdentityModel.Tokens.MetadataBasedIssuerNameRegistry, Thinktecture.IdentityModel">
        <trustedIssuerMetadata issuerName="urn:federation:company:stage" metadataAddress="https://federation-sts-stage.company.com/FederationMetadata/2007-06/FederationMetadata.xml"></trustedIssuerMetadata>
      </issuerNameRegistry>
      <certificateValidation certificateValidationMode="None" />
<securityTokenHandlers>
     <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler,  
             System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

      <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, 
            System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </securityTokenHandlers>
    </identityConfiguration>
  </system.identityModel>

Ответ 5

Удаление cookie FedAuth может работать. Когда возникает исключение, попробуйте это в методе Application_Error файла Global.asax:

Microsoft.IdentityModel.Web.FederatedAuthentication.SessionAuthenticationModule.SignOut();