You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET 4.8 MVC中Azure槽交换时如何保留用户认证Cookie?

ASP.NET 4.8 MVC Azure部署槽交换时持久化认证Cookie方案

针对ASP.NET 4.8 MVC框架,在Azure部署槽(staging/production)交换时保留用户登录Cookie是完全可行的,核心是保证槽之间的认证加密/签名密钥一致,同时Cookie配置跨槽兼容。以下分两种常见认证场景说明:

一、传统Forms Authentication场景

Forms认证的Cookie由机器密钥(Machine Key)加密和签名,槽交换后如果新槽的机器密钥与旧槽不一致,已登录用户的Cookie会直接失效。解决步骤:

  • 显式配置统一机器密钥:在所有部署槽的Web.config中添加相同的<machineKey>节点,不要依赖系统自动生成的密钥。也可以通过Azure App Service的应用设置全局配置,确保所有槽共享该密钥。
    示例Web.config配置:
    <system.web>
      <machineKey validationKey="固定的验证密钥字符串" 
                  decryptionKey="固定的解密密钥字符串" 
                  validation="SHA1" 
                  decryption="AES" />
    </system.web>
    
  • 统一Cookie域名/路径:确保Cookie的Domain配置为父域名(如yourdomain.com),而非槽专属子域名(如staging.yourdomain.com),Path保持默认的/即可。

Owin默认会自动生成本地密钥用于Cookie保护,槽交换后新槽的密钥不同会导致旧Cookie无法验证。解决方式是强制所有槽使用相同的密钥:

  • 自定义数据保护提供器:在Startup.cs中配置CookieAuthenticationOptions时,指定基于固定密钥的DataProtectionProvider,确保所有槽使用同一套加密逻辑。
    示例代码:
    using Microsoft.Owin.Security.DataProtection;
    using System.Security.Cryptography;
    using System.Configuration;
    
    public void Configuration(IAppBuilder app)
    {
        // 从应用设置读取预先生成的固定密钥(所有槽配置相同)
        var protectionKey = Convert.FromBase64String(ConfigurationManager.AppSettings["CookieProtectionKey"]);
    
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            DataProtectionProvider = new DataProtectionProvider(() => new SharedKeyDataProtector(protectionKey))
        });
    }
    
    // 自定义基于固定密钥的数据保护实现
    public class SharedKeyDataProtector : IDataProtector
    {
        private readonly byte[] _sharedKey;
    
        public SharedKeyDataProtector(byte[] sharedKey)
        {
            _sharedKey = sharedKey;
        }
    
        public byte[] Protect(byte[] userData)
        {
            using var aes = Aes.Create();
            aes.Key = _sharedKey;
            aes.GenerateIV();
            var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
    
            using var ms = new MemoryStream();
            ms.Write(aes.IV, 0, aes.IV.Length);
            using var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
            cs.Write(userData, 0, userData.Length);
            return ms.ToArray();
        }
    
        public byte[] Unprotect(byte[] protectedData)
        {
            using var aes = Aes.Create();
            aes.Key = _sharedKey;
            var iv = new byte[aes.BlockSize / 8];
            Array.Copy(protectedData, 0, iv, 0, iv.Length);
            aes.IV = iv;
    
            var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
            using var ms = new MemoryStream();
            using var cs = new CryptoStream(new MemoryStream(protectedData, iv.Length, protectedData.Length - iv.Length), decryptor, CryptoStreamMode.Read);
            cs.CopyTo(ms);
            return ms.ToArray();
        }
    }
    
  • 统一Cookie配置:确保所有槽的Cookie名称、Domain、Path参数完全一致,避免槽间Cookie无法共享。

三、Azure槽配置额外注意事项

  • 在Azure App Service的部署槽设置中,将机器密钥、Cookie保护密钥等关键配置标记为非槽特定(即不勾选"槽设置"选项),确保槽交换时这些配置不会被覆盖。
  • 避免为不同槽配置完全独立的主机名,尽量使用统一域名+路由规则区分槽,保证Cookie可以跨槽传递。

内容的提问来源于stack exchange,提问作者mister_smythers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:36:24