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

ASP.NET Core集成AWS Cognito登出后仍可访问授权区域问题

ASP.NET Core AWS Cognito登出后仍可访问受保护区域问题排查与解决

核心问题定位

调用HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme)仅完成Cognito端的登出流程,但未彻底清除ASP.NET Core应用本地的认证会话,导致带[Authorize]特性的页面/接口仍能被访问。以下是针对性的解决方案:


1. 同时签出Cookie认证方案

ASP.NET Core默认用Cookie存储本地认证会话,仅签出OpenIdConnect方案不足以清除本地状态,需同时触发Cookie方案的签出:

public async Task<IActionResult> Logout()
{
    // 签出Cognito端的OpenIdConnect会话
    await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
    // 清除本地认证Cookie
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    
    return RedirectToAction("Index", "Home");
}

2. 完善OpenIdConnect配置

在Program.cs的认证配置中,关联Cookie方案并配置登出回调,确保Cognito登出后同步清理本地状态:

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.ClientId = builder.Configuration["AWS:Cognito:ClientId"];
    options.ClientSecret = builder.Configuration["AWS:Cognito:ClientSecret"];
    options.Authority = $"https://cognito-idp.{builder.Configuration["AWS:Region"]}.amazonaws.com/{builder.Configuration["AWS:Cognito:UserPoolId"]}";
    options.ResponseType = OpenIdConnectResponseType.Code;
    options.SaveTokens = true;
    
    // 指定登出回调路径
    options.SignedOutCallbackPath = "/signout-callback-oidc";
    // 关联Cookie方案作为登出时的本地清理方案
    options.SignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;

    // 自定义Cognito登出跳转,确保第三方端会话彻底清除
    options.Events = new OpenIdConnectEvents
    {
        OnRedirectToIdentityProviderForSignOut = context =>
        {
            var logoutUri = $"https://{builder.Configuration["AWS:Cognito:Domain"]}.auth.{builder.Configuration["AWS:Region"]}.amazonaws.com/logout?client_id={options.ClientId}&logout_uri={Uri.EscapeDataString(context.Request.Scheme + "://" + context.Request.Host + "/")}";
            context.Response.Redirect(logoutUri);
            context.HandleResponse();
            return Task.CompletedTask;
        }
    };
});

3. 验证Cookie清理状态

登出后打开浏览器开发者工具的Application标签,检查是否存在AspNetCore.Cookies(或自定义名称的认证Cookie)。若仍存在,需检查Cookie配置是否合理:

.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
    options.Cookie.Name = ".AspNetCore.CognitoAuth";
    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
    options.SlidingExpiration = true;
})

4. 清除认证缓存(若使用)

若应用用分布式缓存/内存缓存存储认证票据,登出时需同步删除对应缓存项:

public async Task<IActionResult> Logout(IDistributedCache distributedCache)
{
    var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    if (!string.IsNullOrEmpty(userId))
    {
        await distributedCache.RemoveAsync($"AuthTicket_{userId}");
    }
    
    await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    
    return RedirectToAction("Index", "Home");
}

5. 修正布局页登录状态判断

确保布局页依赖User.Identity.IsAuthenticated判断登录状态,而非本地存储的自定义状态:

@if (User.Identity.IsAuthenticated)
{
    <a asp-controller="Account" asp-action="Logout">登出</a>
}
else
{
    <a asp-controller="Account" asp-action="Login">登录</a>
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:33:24