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

HttpContext.SignOutAsync()未删除本地Cookie的IdentityServer4问题

解决IdentityServer4与ASP.NET Core Identity认证Cookie冲突及登出失效问题

我看你遇到的问题核心是ASP.NET Core Identity和IdentityServer4的认证方案底层冲突了,下面给你拆解原因和具体的修复步骤:

问题根源

你在Startup.cs中同时使用了services.AddIdentity<CustomUser, CustomRole>()和services.AddIdentityServer():

  • AddIdentity会自动注册ASP.NET Core Identity的默认认证方案,生成.AspNetCore.Identity.Application Cookie
  • IdentityServer4自身依赖专属的idsrv Cookie认证方案
    两者的认证逻辑互相干扰,导致出现多余的idsrv.session Cookie,且登出时无法正确清理认证状态。

修复步骤

1. 替换AddIdentity为AddIdentityCore,避免自动注入Identity的认证方案

AddIdentity会自动添加认证中间件和默认方案,我们改用AddIdentityCore只保留用户管理的基础服务,避免干扰IdentityServer的配置:

修改Startup.cs的ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddIdentityServer()
        .AddOperationalStore(options =>
        {
            options.ConfigureDbContext = builder => 
                builder.UseSqlServer(Config.ConnectionString, 
                    sqlOptions => sqlOptions.MigrationsAssembly(Config.MigrationsAssembly));
            options.EnableTokenCleanup = true;
            options.TokenCleanupInterval = 30;
        })
        .AddConfigurationStore(options =>
        {
            options.ConfigureDbContext = builder => 
                builder.UseSqlServer(Config.ConnectionString, 
                    sqlOptions => sqlOptions.MigrationsAssembly(Config.MigrationsAssembly));
        })
        .AddDeveloperSigningCredential();

    services.AddDbContext<CustomUserContext>(builder => 
        builder.UseSqlServer(Config.ConnectionString, 
            sqlOptions => sqlOptions.MigrationsAssembly(Config.MigrationsAssembly)));

    // 替换AddIdentity为AddIdentityCore,手动注册必要服务
    services.AddIdentityCore<CustomUser>()
        .AddRoles<CustomRole>()
        .AddEntityFrameworkStores<CustomUserContext>()
        .AddSignInManager() // 手动添加SignInManager
        .AddUserManager<UserManager<CustomUser>>(); // 手动添加UserManager

    // 明确指定默认认证方案为IdentityServer的Cookie方案
    services.AddAuthentication(options =>
    {
        options.DefaultScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme;
        options.DefaultChallengeScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme;
    });
}

2. 登录时明确指定IdentityServer的认证方案

修改AccountController中的Login方法,确保生成的是IdentityServer的idsrv Cookie:

//Issue Auth Cookie
await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme); // 先清除可能存在的旧会话

// 构建用户Claims
var claims = new List<Claim>
{
    new Claim(ClaimTypes.NameIdentifier, user.Id),
    new Claim(ClaimTypes.Name, user.UserName)
    // 可添加其他需要的Claim,比如角色、邮箱等
};

var identity = new ClaimsIdentity(claims, IdentityServerConstants.DefaultCookieAuthenticationScheme);
var principal = new ClaimsPrincipal(identity);

await HttpContext.SignInAsync(
    IdentityServerConstants.DefaultCookieAuthenticationScheme,
    principal,
    props
);

3. 登出时明确指定认证方案

修改Logout方法,确保清理IdentityServer的认证Cookie:

[HttpGet]
public async Task Logout(LogoutInputModel model)
{
    if (User?.Identity.IsAuthenticated == true)
    {
        // 明确指定登出IdentityServer的Cookie方案
        await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
        await _eventService.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
    }
}

验证效果

修改完成后重新运行项目:

  • 登录时应该只会生成Antiforgery Validation和idsrv两个Cookie,与示例项目一致
  • 执行登出操作后,idsrv Cookie会被删除,用户身份变为未认证状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:09:05