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

Docker部署ASP.NET Core+PostgreSQL时防伪令牌解密失败问题排查

问题描述

使用Docker编排部署ASP.NET Core镜像与PostgreSQL镜像,测试学生数据创建功能时,返回错误提示:"The antiforgery token could not be decrypted."。该功能用于向PostgreSQL数据库写入学生信息,相关代码如下:

CreateStudent接口代码

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,FirstName,LastName,Email")] Student student)
{
    if (ModelState.IsValid)
    {
        _context.Add(student);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(student);
}

create.cshtml视图代码

@model _netcoreApi.Models.Student

@{
    ViewData["Title"] = "Create";
}

<h1>Registro</h1>

<h4>Estudiante</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Id" class="control-label"></label>
                <input asp-for="Id" class="form-control" />
                <span asp-validation-for="Id" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="FirstName" class="control-label"></label>
                <input asp-for="FirstName" class="form-control" />
                <span asp-validation-for="FirstName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="LastName" class="control-label"></label>
                <input asp-for="LastName" class="form-control" />
                <span asp-validation-for="LastName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Email" class="control-label"></label>
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>
原因分析

该错误源于防伪令牌解密失败,结合Docker部署场景,常见触发原因包括:

  • 临时加密密钥未持久化:ASP.NET Core默认自动生成临时加密密钥,容器重启后密钥丢失,导致之前生成的令牌无法解密。
  • 表单未携带有效防伪令牌:视图或布局页未正确生成防伪令牌,导致提交时令牌缺失或无效。
  • 多实例密钥不一致:若部署多个ASP.NET Core容器实例,各实例使用独立密钥,跨实例提交的令牌无法被验证。
修复方案

1. 持久化加密密钥(Docker环境核心修复)

通过配置固定加密密钥,确保容器重启或多实例场景下密钥一致:

  • 方式一:配置文件设置
    修改appsettings.json添加密钥:
{
  "DataProtection": {
    "Keys": {
      "Key1": "生成32位以上随机字符串作为密钥"
    }
  }
}
  • 方式二:Docker环境变量传递
    在docker-compose.yml中为ASP.NET Core服务添加环境变量:
services:
  aspnetcore-app:
    environment:
      - ASPNETCORE_DATA_PROTECTION_KEYS__KEY1=你的32位以上随机密钥字符串
  • 可选:持久化密钥到共享存储
    在Program.cs中配置数据保护,将密钥存储到挂载的Docker卷:
builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo("/app/DataProtectionKeys"))
    .SetApplicationName("StudentManagementApp");

同时在docker-compose.yml中添加卷挂载:

volumes:
  - ./data-protection-keys:/app/DataProtectionKeys

2. 确保表单携带防伪令牌

在create.cshtml的<form>标签内添加防伪令牌生成代码:

@Html.AntiForgeryToken()

或检查布局页(如_Layout.cshtml)是否包含@await Html.RenderPartialAsync("_ValidationScriptsPartial"),确保Tag Helper自动生成令牌。

3. 多实例场景统一密钥

若部署多个ASP.NET Core容器,必须保证所有实例使用相同加密密钥,优先采用共享存储持久化密钥或统一环境变量传递密钥的方式,避免各实例密钥独立。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:57:14