多Cookie认证方案下普通用户IsAuthenticated返回false问题求助
问题原因
你的配置中,默认认证方案(DefaultAuthenticateScheme)被设置为管理员的Cookie方案(CookieAuthenticationDefaults.AuthenticationScheme),这意味着ASP.NET Core默认只会自动验证管理员的Cookie。普通用户登录时使用的是名为"user"的独立Cookie方案,默认流程不会主动验证该方案的Cookie,因此User.Identity.IsAuthenticated返回false。只有当你通过[Authorize(AuthenticationSchemes = "user")]指定要验证该方案时,系统才会触发对应Cookie的验证,此时IsAuthenticated才会返回true。
解决方案
方案1:修改默认认证方案,同时尝试两种Cookie
直接在AddAuthentication配置中,将默认认证和挑战方案设置为包含管理员和普通用户的两个方案,系统会依次尝试验证这些方案的Cookie,只要有一个验证通过,就会标记用户为已认证:
builder.Services.AddAuthentication(option => { // 默认登录方案仍保留为管理员Cookie(可根据业务需求调整) option.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; // 设置默认认证方案同时尝试管理员和普通用户的Cookie option.DefaultAuthenticateScheme = $"{CookieAuthenticationDefaults.AuthenticationScheme},user"; option.DefaultChallengeScheme = $"{CookieAuthenticationDefaults.AuthenticationScheme},user"; }).AddCookie(option => // 管理员认证方案 { option.LoginPath = new PathString("/admin/auth/login"); option.ExpireTimeSpan = TimeSpan.FromMinutes(1); option.AccessDeniedPath = new PathString("/"); }).AddCookie("user", option => // 普通用户认证方案 { option.LoginPath = new PathString("/"); option.ExpireTimeSpan = TimeSpan.FromMinutes(1); option.AccessDeniedPath = new PathString("/"); });
方案2:创建全局授权策略,包含两种认证方案
通过定义全局授权策略,让系统默认同时验证两种Cookie方案,无需在每个接口单独指定认证方案:
// 先注册两种Cookie认证方案 builder.Services.AddAuthentication() .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, option => { option.LoginPath = new PathString("/admin/auth/login"); option.ExpireTimeSpan = TimeSpan.FromMinutes(1); option.AccessDeniedPath = new PathString("/"); }) .AddCookie("user", option => { option.LoginPath = new PathString("/"); option.ExpireTimeSpan = TimeSpan.FromMinutes(1); option.AccessDeniedPath = new PathString("/"); }); // 添加全局授权策略,要求用户通过任意一种认证方案验证 builder.Services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder( CookieAuthenticationDefaults.AuthenticationScheme, "user") .RequireAuthenticatedUser() .Build(); });
方案3:针对普通用户接口统一指定认证方案
如果不需要全局启用两种方案验证,可以为普通用户相关的控制器或接口统一添加[Authorize(AuthenticationSchemes = "user")]特性,这样访问这些接口时系统会自动验证"user"方案的Cookie,User.Identity.IsAuthenticated会返回true。
验证说明
无论采用哪种方案,现有登录逻辑无需修改:管理员登录时使用默认方案签名,普通用户登录时指定"user"方案签名即可。调整配置后,普通用户登录后访问未指定特定方案的接口时,系统会自动验证其Cookie,User.Identity.IsAuthenticated将返回true。
内容的提问来源于stack exchange,提问作者Ali.M Eghbaldar

