Asp.net mvc 使用ACS扩展Azure Web角色时的保护API异常

Asp.net mvc 使用ACS扩展Azure Web角色时的保护API异常,asp.net-mvc,azure,azure-web-roles,acs,Asp.net Mvc,Azure,Azure Web Roles,Acs,我一直在对Windows Live和Google使用Azure ACS,而且运行起来没有任何问题。昨晚,我们将实例从1个运行实例扩展到3个,从那时起,人们在访问我们的站点时报告了问题。我们将此追溯到以下异常,该异常在相当定期的基础上发生 我们假设配置中存在问题,但不确定缺少什么。我们设置了机器钥匙 <machineKey decryption="AES" decryptionKey="F7_SOMETHING_SOMETHING_FA" validation="SHA1" validati

我一直在对Windows Live和Google使用Azure ACS,而且运行起来没有任何问题。昨晚,我们将实例从1个运行实例扩展到3个,从那时起,人们在访问我们的站点时报告了问题。我们将此追溯到以下异常,该异常在相当定期的基础上发生

我们假设配置中存在问题,但不确定缺少什么。我们设置了机器钥匙

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

注意:用于上下文。这是在Windows Azure Web角色中运行的,是MVC 4。

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

Windows身份基础(WIF)是一种带外运行时,必须安装在计算机上,这样您的声明意识的应用程序就可以使用它。默认情况下,Windows Azure实例上未安装WIF。要运行支持云声明的应用程序,必须在Windows Azure实例上提供WIF运行时。最简单的方法是将WIF程序集包含在部署包中

将WIF程序集包括在Windows Azure部署包中

  • 在解决方案资源管理器中,找到索赔感知应用程序
  • 展开“引用”文件夹
  • 在References文件夹下找到Microsoft.IdentityModel程序集
  • 在部件上单击鼠标右键,然后单击“特性”
  • 在“属性”窗口中,将“复制本地”指定为True,将“特定版本”指定为False
  • 默认情况下,WIF使用数据保护应用程序编程接口(DPAPI)以加密方式保护cookie。DPAPI在Windows Azure上不可用。为了确保您的云声明感知web应用程序在部署到Windows Azure时能够正确运行,您必须使用RSA添加Cookie加密功能

    使用RSA加密Cookie

  • 在解决方案资源管理器中,找到您的云声明感知web应用程序
  • 在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;
    
    void onServiceConfiguration已创建(对象发送方,ServiceConfigurationCreatedEventArgs e)
    {
    //
    //使用来保护正在使用的cookie
    //发送到客户端。
    //
    列出会话转换表单=
    新列表(新CookietTransform[]{
    新的deflateCookietTransform(),
    新的RsaEncryptionCookieTransform(例如ServiceConfiguration.ServiceCertificate),
    新的RSASignatureCookietTransform(e.ServiceConfiguration.ServiceCertificate)});
    SessionSecurityTokenHandler sessionHandler=新建SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());
    e、 ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);
    }
    无效应用程序\u启动(对象发送方,事件参数e)
    {
    FederatedAuthentication.ServiceConfigurationCreated+=OnServiceConfiguration Created;
    

    更多信息可在此处找到:

    这是在
    农场
    环境中使用WIF时的常见异常。问题是默认行为是使用DPAPI加密cookie。但是DPAPI是MachineKey绑定的


    您必须在Global.Asax中进行一个小的更改,并使用RSA Crypto service provider对FedAuth Cookie进行加密/解密。请看。

    我在尝试将ACS与部署为Windows Azure网站实例而不是云服务的MVC 4应用程序一起使用时遇到了类似的问题。以下内容帮助我解决了该问题。

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

    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;