9

我一直在针对 Windows Live 和 Google 使用 Azure ACS,它的运行没有任何问题。昨晚我们将实例从 1 个运行实例扩展到 3 个,从那时起人们在访问我们的站点时报告了问题。我们已经将此追溯到以下经常发生的异常。

我们假设我们的配置中的某个地方存在问题,但不确定我们缺少什么。我们设置机器密钥...

<machineKey decryption="AES" decryptionKey="F7_SOMETHING_SOMETHING_FA" validation="SHA1" validationKey="63_SOMETHING_SOMETHING_BF" />

任何人都可以阐明这个问题吗?

System.InvalidOperationException: ID1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details). If you are using IIS 7.5, this could be due to the loadUserProfile setting on the Application Pool being set to false.  ---> System.Security.Cryptography.CryptographicException: 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)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded)
   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound)
   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver)
   at Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie)
   at Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken)
   at Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

注意:为了上下文。这是在 Windows Azure Web 角色中运行的,并且是 MVC 4。

4

3 回答 3

7

既然您已经向外扩展并且由于您的应用程序托管在负载均衡器后面,那么您的用户可能导航到服务器 A,在服务器 A 上获得了受 DPAPI 保护的会话 cookie,但是当他们继续浏览该站点时负载均衡器将请求重定向到服务器B上执行。发生这种情况时,服务器B没有匹配的机器密钥,因此无法解密会话cookie并抛出上述错误。以下是您可以解决此问题的三种方法。

Windows Identity Foundation (WIF) 是一个带外运行时,必须安装在计算机上,以便您的声明感知应用程序可以使用它。默认情况下,Windows Azure 实例上未安装 WIF。要运行云声明感知应用程序,您必须使 WIF 运行时在 Windows Azure 实例上可用。最简单的方法是在部署包中包含 WIF 程序集。

在 Windows Azure 部署包中包含 WIF 程序集

  1. 在解决方案资源管理器中,找到您的声明感知应用程序。
  2. 展开引用文件夹。
  3. 在 References 文件夹下找到 Microsoft.IdentityModel 程序集。
  4. 右键单击该程序集,然后单击“属性”。
  5. 在属性窗口中,将 Copy Local 指定为 True,将特定版本指定为 False。

默认情况下,WIF 使用数据保护应用程序编程接口 (DPAPI) 以加密方式保护 cookie。DPAPI 在 Windows Azure 上不可用。为确保您的云声明感知 Web 应用程序在部署到 Windows Azure 时能够正常运行,您必须使用 RSA 添加 cookie 加密功能。

使用 RSA 加密 cookie

  1. 在解决方案资源管理器中,找到您的云声明感知 Web 应用程序。
  2. 在 Visual Studio 编辑器中打开 global.asax.cs 文件,它是 global.asax 文件背后的代码。

添加以下声明:

using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Web;
using Microsoft.IdentityModel.Web.Configuration;

添加以下代码:

void OnServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e)
{
    //
    // Use the <serviceCertificate> to protect the cookies that are
    // sent to the client.
    //
    List<CookieTransform> sessionTransforms =
        new List<CookieTransform>(new CookieTransform[] {
        new DeflateCookieTransform(), 
        new RsaEncryptionCookieTransform(e.ServiceConfiguration.ServiceCertificate),
        new RsaSignatureCookieTransform(e.ServiceConfiguration.ServiceCertificate)  });
    SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());
    e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);
}

void Application_Start(object sender, EventArgs e)
{
    FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated;

更多信息可以在这里找到:http: //msdn.microsoft.com/en-us/library/hh289318.aspx

于 2012-12-19T13:27:30.403 回答
2

farm这是在环境中使用 WIF 时的常见异常。关键是默认行为是使用 DPAPI 来加密 cookie。但是 DPAPI 是 MachineKey 绑定的。

您必须在 Global.Asax 中做一个小改动,并使用 RSA Crypto 服务提供商来加密/解密 FedAuth Cookie。看看这篇文章如何实现这一点

于 2012-12-19T13:28:59.917 回答
1

在尝试将 ACS 与部署为 Windows Azure 网站实例与云服务的 MVC 4 应用程序一起使用时,我遇到了类似的问题。以下帮助我解决了这个问题。 http://msdn.microsoft.com/en-us/library/hh568644.aspx

滚动到最底部并找到显示删除 SessionSecurityTokenHandler 并将其替换为 MachineKeySessionSecurityTokenHandler 的示例。

于 2013-09-16T17:11:27.940 回答