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

基于数据库存储的Data Protection密钥加密.Net Core与.Net Framework 4.x认证Cookie

这个跨框架共享认证Cookie的场景我之前帮不少开发者踩过坑,核心就是让.NET Framework和.NET Core的DataProtection系统完全对齐,同时用数据库作为密钥的统一存储源,这样多台服务器都能共享密钥。下面一步步来实现:

实现步骤详解

1. 准备数据库存储密钥

首先需要在数据库中创建存储Data Protection密钥的表,以SQL Server为例,执行以下SQL脚本:

CREATE TABLE DataProtectionKeys (
    Id NVARCHAR(450) PRIMARY KEY,
    Xml NVARCHAR(MAX) NOT NULL,
    CreationDate DATETIME2 NOT NULL
);

这个表结构是Data Protection框架默认要求的:Id是密钥的唯一标识,Xml存储密钥的序列化内容,CreationDate记录密钥创建时间。

2. 配置.NET Core 2.0应用

2.1 安装必要的NuGet包

在你的.NET Core 2.0项目中安装以下包:

Install-Package Microsoft.AspNetCore.DataProtection.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.SqlServer

2.2 创建Data Protection DbContext

创建一个继承自DbContext的类,用于操作密钥表:

using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

public class DataProtectionKeysContext : DbContext, IDataProtectionKeyContext
{
    public DataProtectionKeysContext(DbContextOptions<DataProtectionKeysContext> options)
        : base(options) { }

    // 对应数据库中的DataProtectionKeys表
    public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
}

2.3 配置Data Protection和Cookie认证

在Startup.cs的ConfigureServices方法中添加以下配置:

public void ConfigureServices(IServiceCollection services)
{
    // 配置Data Protection使用数据库存储密钥
    services.AddDbContext<DataProtectionKeysContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DataProtectionKeys")));

    services.AddDataProtection()
        // 设置统一的应用名称,两个应用必须完全一致
        .SetApplicationName("SharedCookieApp")
        // 配置使用数据库存储密钥
        .PersistKeysToDbContext<DataProtectionKeysContext>()
        // 指定加密算法,确保和.NET Framework端一致
        .UseCryptographicAlgorithms(new AuthenticatedEncryptionSettings
        {
            EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
            ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
        });

    // 配置Cookie认证,和.NET Framework端共享Cookie
    services.AddAuthentication("SharedCookie")
        .AddCookie("SharedCookie", options =>
        {
            options.Cookie.Name = ".AspNet.SharedCookie";
            // 设置Cookie的域名,如果应用部署在同域名下的不同子域名,比如*.example.com
            options.Cookie.Domain = ".example.com";
            options.Cookie.Path = "/";
            options.Cookie.HttpOnly = true;
            options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 生产环境建议启用HTTPS
        });

    // 其他服务配置...
}

别忘了在Configure方法中启用认证中间件:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // 其他中间件...
    app.UseAuthentication();
    // 其他中间件...
}

3. 配置.NET Framework 4.x应用

3.1 安装必要的NuGet包

在你的.NET Framework 4.x项目中安装以下包:

Install-Package Microsoft.AspNet.DataProtection.EntityFramework
Install-Package EntityFramework
Install-Package Microsoft.AspNet.DataProtection.SystemWeb

3.2 创建Data Protection DbContext(EF6版本)

因为.NET Framework用的是Entity Framework 6,所以DbContext需要继承自EF6的DbContext:

using Microsoft.AspNet.DataProtection.EntityFramework;
using System.Data.Entity;

public class DataProtectionKeysContext : DbContext, IDataProtectionKeyContext
{
    public DataProtectionKeysContext()
        : base("Name=DataProtectionKeys") { } // 对应web.config中的连接字符串名称

    public IDbSet<DataProtectionKey> DataProtectionKeys { get; set; }
}

3.3 配置Data Protection和Cookie认证

如果你的应用使用传统Forms认证,在Global.asax的Application_Start方法中添加以下配置:

using Microsoft.AspNet.DataProtection;
using System.Web.Security;

protected void Application_Start()
{
    // 配置Data Protection
    var dataProtectionProvider = DataProtectionProvider.Create()
        .PersistKeysToDbContext<DataProtectionKeysContext>()
        .SetApplicationName("SharedCookieApp") // 和Core应用名称完全一致
        .UseCryptographicAlgorithms(new AuthenticatedEncryptionSettings
        {
            EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
            ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
        });

    // 配置FormsAuthentication使用Data Protection加密Cookie
    FormsAuthentication.EnableFormsAuthentication(new FormsAuthenticationOptions
    {
        CookieName = ".AspNet.SharedCookie",
        CookieDomain = ".example.com", // 和Core端一致
        CookiePath = "/",
        HttpOnly = true,
        Secure = true, // 生产环境建议启用
        DataProtectionProvider = dataProtectionProvider
    });

    // 其他初始化代码...
}

如果是使用OWIN的Cookie认证(比如ASP.NET MVC 5+),则在OWIN Startup类中配置:

using Microsoft.AspNet.DataProtection;
using Microsoft.Owin.Security.Cookies;
using Owin;

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var dataProtectionProvider = DataProtectionProvider.Create("SharedCookieApp")
            .PersistKeysToDbContext<DataProtectionKeysContext>()
            .UseCryptographicAlgorithms(new AuthenticatedEncryptionSettings
            {
                EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
                ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
            });

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "SharedCookie",
            CookieName = ".AspNet.SharedCookie",
            CookieDomain = ".example.com",
            CookiePath = "/",
            HttpOnly = true,
            Secure = CookieSecureOption.Always,
            DataProtectionProvider = dataProtectionProvider
        });
    }
}

同时在web.config中配置正确的数据库连接字符串:

<connectionStrings>
    <add name="DataProtectionKeys" connectionString="Server=your-server;Database=your-db;User Id=your-user;Password=your-password;" providerName="System.Data.SqlClient" />
</connectionStrings>

4. 关键注意事项

  • 应用名称必须完全一致:两个应用的SetApplicationName参数要一模一样,Data Protection框架靠这个识别"同一个应用",才能复用密钥。
  • 数据库权限要到位:所有Web服务器的应用池账户必须拥有DataProtectionKeys表的读写权限,确保能正常存取密钥。
  • Cookie配置完全统一:Cookie的名称、域名、路径、HttpOnly、Secure等属性必须完全相同,否则浏览器不会在两个应用间共享Cookie。
  • 加密算法严格对齐:两个应用必须使用相同的加密算法组合,不然无法解密对方生成的Cookie内容。
  • 多服务器无需文件共享:密钥存在数据库后,所有服务器都会从同一个数据源读取密钥,不用再配置复杂的共享文件系统。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:06:36