【问题标题】:Microsoft.IdentityModel: Key not valid for use in specified stateMicrosoft.IdentityModel:密钥在指定状态下无效
【发布时间】:2012-01-04 01:02:03
【问题描述】:

我有一个使用 Windows Identity Foundation 的声明感知 Web 应用程序,该应用程序运行良好,但在一台服务器上除外。我在事件日志中看到如下所示的错误消息。

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)

此应用程序使用带有 ADFS v2 的非常标准的 WIF 实现。它没有使用 RsaEncryptionCookieTransform。我正在寻找有关如何诊断此问题的任何建议。到目前为止我尝试过的事情:

  1. 应用程序池正在使用 ASP.NET v4.0 身份,其“加载用户配置文件”设置设置为 true。
  2. 我删除了 C:\Users\ASP.NET v4.0\AppData 文件夹,发现它已成功重新创建。
  3. 我检查了证书私钥的权限,这很好。我还尝试禁用令牌加密,但没有任何区别。

任何建议将不胜感激。

【问题讨论】:

    标签: cryptography wif


    【解决方案1】:

    这通常是由于应用程序无法解密身份验证令牌 cookie 造成的。确保拥有 App Pool 的身份具有足够的权限来访问您的证书存储。尝试将身份更改为NetworkService,看看是否有帮助。

    您还应该清除浏览器的 cookie,以确保您没有缓存来自其他应用程序的 cookie。

    【讨论】:

    • 谢谢。您证实了我的怀疑,这是与 cookie 相关的,所以我做了很多试验和错误,发现这是由另一个 WIF 安全 Web 应用程序(在另一台服务器上)创建一个带有 / 路径的 WIF cookie 显然试图解密的通过这个网络应用程序。我通过调整两个应用程序使用的路径值来解决这个问题。奇怪的是,我只在 IE 上看到了这个错误,而不是 Firefox/Chrome。我将不得不花更多时间来更好地理解这个问题。
    • 我遇到了同样的事情。很高兴你解决了。我不确定为什么你只会在 IE 中看到这个,但更改 cookie 路径应该是解决方法。
    • 我不小心删除了本地网站后遇到了同样的问题。删除 wif 和 asp.net cookie 就成功了。
    • 在将我的负载均衡器更改为指向不同的环境后遇到了同样的问题。清除我的缓存解决了错误。
    【解决方案2】:

    问题是 100% 可重现的:

    确实,在重新部署应用程序后,旧的身份验证 cookie 留在客户端计算机上(客户端未注销) - 在任何后续请求中都会向客户端显示此错误。 要修复此错误,客户端必须删除 cookie 和/或登录然后从 STS 注销。一旦完成 - 错误消失,一切都很好,直到下一次升级......

    经过一番研究,我认为这是 SessionAuthenticationModule 中的一个需要修复的错误。如果您仔细查看上面的堆栈跟踪,有一个有趣的方法叫做 TryReadSessionTokenFromCookie,它设置期望认证模块将“尝试”从 cookie 中读取令牌,如果失败将返回 false - 这是代码(感谢更清晰!):

    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 之外还能做些什么来处理它。 非常感谢任何帮助!!! 谢谢! 亚历克斯

    【讨论】:

    • Application_Error 全局处理程序似乎是合适的地方。 var exc = Server.GetLastError(); if (exc is CryptographicException || exc.InnerException is CryptographicException) { Server.ClearError(); ResetAuthentication(); } 这样的东西对我有用。
    【解决方案3】:

    这个错误似乎没有被 http 应用程序捕获。 请改用http://social.technet.microsoft.com/wiki/contents/articles/1898.aspx#Q1

    【讨论】:

      【解决方案4】:

      删除FedAuth cookie 可能有效。当异常发生时,在Global.asax文件的Application_Error方法中试试这个:

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

      【讨论】:

        【解决方案5】:

        我解决了我的问题,因为我有两个应用程序的相同 cookie 名称“FedAuth”(这是默认名称)。只需输入不同的名称即可解决:

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

        【讨论】:

          【解决方案6】:

          以下内容对我有用:

          您需要在 system.identityModel/identityConfiguration 中添加部分

          参考: SessionSecurityTokenHandler trying to decrypt SessionSecurityToken in RSA-encrypted cookie using DPAPI; why?

            <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>
          

          【讨论】:

            【解决方案7】:

            这个问题是因为权限不足。 应用程序池应具有 ApplicationPoolIdentity 身份才能使其工作。 转到您的应用程序池 -> 高级设置 -> 内置帐户以更改设置

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-10-03
              • 1970-01-01
              • 1970-01-01
              • 2013-09-11
              • 2014-06-24
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多