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

ASP.NET 6 Restful Api Cookie认证无法通过身份验证问题

问题根因

从日志和代码看,认证不生效是4个核心问题叠加导致的:

  • AddDefaultIdentity 方法会自动覆盖你之前手动配置的默认认证方案,内部强制注册名为Identity.Application的Cookie方案作为默认校验方案,你自定义的caloryCookieAuth仅在登录时被使用,后续请求校验身份时根本不会走这个方案,和日志里AuthenticationScheme: Identity.Application was challenged的记录完全对应。
  • 你是纯RESTful API项目,Cookie认证默认的未授权逻辑是返回302重定向到Razor登录页,但你项目里根本没有对应的Razor页面,才会出现跳转到/Identity/Account/Login返回404的问题。
  • 登录逻辑里手动构造ClaimsPrincipal的写法绕过了ASP.NET Core Identity的标准认证流程,签发的Cookie不符合Identity的校验规则。
  • 用Postman/Fiddler调试时没有开启Cookie自动持久化,登录接口返回的Set-Cookie头没有被保存,后续请求根本没携带认证Cookie。
修复步骤

1. 修改Program.cs服务配置

删除你之前手动写的AddAuthentication配置块,替换AddDefaultIdentity为AddIdentity(避免默认方案被覆盖),同时配置Cookie认证适配API场景:

builder.Services.AddDbContext<AppDbContext>(o =>
    o.UseSqlServer(builder.Configuration["ConnectionStrings:DefaultConnection"]));

// 替换原来的AddDefaultIdentity
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
    options.User.RequireUniqueEmail = true;
    // 作业不需要邮箱/账号确认,直接关闭
    options.SignIn.RequireConfirmedAccount = false;
    options.SignIn.RequireConfirmedEmail = false;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddSignInManager()
.AddCookie(options =>
{
    options.Cookie.Name = "caloryCookieAuth";
    // 本地HTTPS调试用Lax即可,None必须配合SecurePolicy.Always使用否则会被浏览器拦截
    options.Cookie.SameSite = SameSiteMode.Lax;
    options.Cookie.HttpOnly = true;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    options.ExpireTimeSpan = TimeSpan.FromDays(1);
    options.SlidingExpiration = true;

    // 核心配置:纯API场景禁止302跳转,直接返回标准HTTP状态码
    options.Events.OnRedirectToLogin = context =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return Task.CompletedTask;
    };
    options.Events.OnRedirectToAccessDenied = context =>
    {
        context.Response.StatusCode = StatusCodes.Status403Forbidden;
        return Task.CompletedTask;
    };
});

2. 修正中间件顺序

中间件顺序必须严格按照如下排列,没有自定义Cookie策略的话直接删掉UseCookiePolicy避免拦截Cookie:

app.UseHttpsRedirection();
// app.UseCookiePolicy(); // 无特殊需求注释掉这行
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.Run();

3. 修正登录/登出接口逻辑

不要手动构造ClaimsIdentity,直接用SignInManager提供的标准方法,自动签发/清理符合Identity规则的认证Cookie:

[AllowAnonymous]
[HttpPost("login")]
public async Task<ActionResult> LoginAsync([FromBody] LoginModelType loginModelType)
{
    // 直接调用Identity内置的密码校验+登录方法,自动签发Cookie
    var signInResult = await _signInManager.PasswordSignInAsync(
        userName: loginModelType.Email,
        password: loginModelType.Password,
        isPersistent: false,
        lockoutOnFailure: false); // 作业场景不需要用户锁定功能直接关闭

    if (signInResult.Succeeded)
    {
        return NoContent();
    }
    return BadRequest("用户认证失败,请重试!");
}

[HttpPost("logout")]
public async Task<ActionResult> LogoutAsync()
{
    await _signInManager.SignOutAsync();
    return NoContent();
}

4. 调试工具配置

  • Postman:开启设置里的Automatically save and send cookies选项,确保登录接口返回的Cookie被自动存入Cookie Jar,后续同域名请求会自动携带。
  • Fiddler:Composer面板开启Persist cookies选项,自动维护请求Cookie。
  • 测试前先清空本地localhost域名下存储的所有旧Cookie,避免历史无效Cookie干扰认证结果。
验证结果

修改完成后重启项目,先调用登录接口返回204,再调用/api/User/getDemoAuthorized接口,会正常返回200和业务数据,未登录时访问会直接返回401状态码,不再出现302跳转和404问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:42:16