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

ASP.NET Core 5 登出功能失效问题求助

ASP.NET Core 5 登出功能失效问题解决

问题描述

ASP.NET Core 5项目中登出功能无法正常运行:执行登出操作后,原本需要授权验证的功能仍处于已登录状态,无需重新认证即可直接访问。

相关代码

Startup.cs

namespace ERP
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();

            #region Authenication
            services.AddAuthentication()
            .AddCookie("ProvinceArea", options =>
             {
                 options.Cookie.Name = "ProvinceArea";
                 options.LoginPath = "/PLogin";
                 options.LogoutPath = "/PLogout";
                 options.ExpireTimeSpan = TimeSpan.FromHours(12);
             }).AddCookie("CountyArea", options =>
             {
                 options.Cookie.Name = "CountyArea";
                 options.LoginPath = "/CLogin";
                 options.LogoutPath = "/CLogout";
                 options.ExpireTimeSpan = TimeSpan.FromHours(12);
             }).AddCookie("DistrictArea", options =>
             {
                 options.Cookie.Name = "DistrictArea";
                 options.LoginPath = "/DLogin";
                 options.LogoutPath = "/DLogout";
                 options.ExpireTimeSpan = TimeSpan.FromHours(12);
             });
            #endregion

            #region Db Context
            services.AddDbContext<ERPContext>(options =>
                { options.UseSqlServer("Data Source =.;Initial Catalog=ERP_DB;Integrated Security=true"); });
            #endregion

            #region IOC
            services.AddTransient<IManagementService, ManagementService>();
            #endregion 
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                name: "areas",
                pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
             );
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

登录与登出方法

[Route("PLogin")]
public IActionResult PLogin()
{
    return View();
}

[HttpPost]
[Route("PLogin")]
public IActionResult PLogin(LoginViewModel login)
{
    if (!ModelState.IsValid)
    {
        return View(login);
    }

    var user = _ManagementService.PLoginUser(login);
    if (user != null)
    {
        var claims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier,user.nationalCode.ToString()),
                new Claim("nationalCode",user.nationalCode.ToString()),
                new Claim("fName",user.fName.ToString()),
                new Claim("lName",user.lName.ToString()),
                new Claim("department",user.department.ToString()),
                new Claim("role",user.role.ToString())
            };

        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        var principal = new ClaimsPrincipal(identity);

        HttpContext.SignInAsync("ProvinceArea", principal);

        ViewBag.IsSuccess = true;
        return View(login);
    }
    ModelState.AddModelError("nationalCode", "کاربری با مشخصات وارد شده یافت نشد");
    return View(login);
}

#endregion

#region Logout
//تابع خروج
[Route("PLogout")]
public IActionResult PLogout()
{
    HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    return Redirect("/PLogin");
}
#endregion

授权控制器代码

namespace ERP.Areas.ProvinceArea.Controllers
{ 
    [Area("ProvinceArea")]
    [Authorize(AuthenticationSchemes = "ProvinceArea")]

    public class HomeController : Controller
    {

问题原因与解决方法

核心问题

登出操作未针对正确的认证Scheme执行,导致对应登录Cookie未被清除:

  1. 登录时使用的是自定义Scheme ProvinceArea,但登出时调用SignOutAsync传入的是默认Scheme CookieAuthenticationDefaults.AuthenticationScheme,两者不匹配。
  2. 登录时创建ClaimsIdentity使用的是默认Scheme,与认证Cookie的Scheme不一致,可能导致身份验证逻辑混乱。

修正步骤

1. 修正登出方法

将登出方法中的SignOutAsync参数改为对应的Scheme名称ProvinceArea:

[Route("PLogout")]
public IActionResult PLogout()
{
    HttpContext.SignOutAsync("ProvinceArea");
    return Redirect("/PLogin");
}

2. 修正登录时的ClaimsIdentity认证类型

登录时创建ClaimsIdentity,需指定与登录Scheme一致的认证类型:

var identity = new ClaimsIdentity(claims, "ProvinceArea");
var principal = new ClaimsPrincipal(identity);

HttpContext.SignInAsync("ProvinceArea", principal);

3. (可选)确保登出时清除Cookie

如果仍有问题,可以显式指定Cookie选项确保清除:

await HttpContext.SignOutAsync("ProvinceArea", new AuthenticationProperties
{
    RedirectUri = "/PLogin"
});

验证修正效果

完成上述修改后,执行登出操作后,访问ProvinceArea区域下的授权页面,会自动跳转到登录页,说明登出功能正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:26:59