.NET Core OAuth集成问题:调用SignInAsync后SignInManager.IsSignedIn返回false
你遇到的核心问题是SignInManager默认使用的认证Scheme和你配置的Cookie Scheme不匹配,导致它无法识别你通过OAuth回调创建的登录状态。我来帮你一步步排查和解决:
1. 明确Scheme的差异
你目前配置的Cookie认证用的是CookieAuthenticationDefaults.AuthenticationScheme,但ASP.NET Core Identity的SignInManager默认会使用IdentityConstants.ApplicationScheme作为登录Scheme。这两个是不同的标识,所以即便你用Cookie保存了登录态,SignInManager也认不出来。
2. 统一所有相关的Scheme
解决办法是把所有涉及登录的Scheme统一成同一个,推荐使用Identity的默认Scheme,这样SignInManager能直接识别。修改你的Startup.cs配置:
services.AddAuthentication(options => { // 把默认Scheme设为Identity的Application Scheme options.DefaultScheme = IdentityConstants.ApplicationScheme; options.DefaultChallengeScheme = MicrosoftAccountDefaults.AuthenticationScheme; }) // 用Identity的Scheme注册Cookie认证 .AddCookie(IdentityConstants.ApplicationScheme) .AddMicrosoftAccount(microsoftOptions => { microsoftOptions.ClientId = "..."; microsoftOptions.ClientSecret = "..."; // 这里的SignInScheme也要和上面保持一致 microsoftOptions.SignInScheme = IdentityConstants.ApplicationScheme; });
如果你是用AddDefaultIdentity或AddIdentity注册Identity服务,也可以显式指定SignInScheme:
services.AddDefaultIdentity<IdentityUser>() .AddEntityFrameworkStores<ApplicationDbContext>() // 指定SignInScheme和Cookie认证的Scheme一致 .AddSignInManager(options => options.SignInScheme = IdentityConstants.ApplicationScheme);
3. 检查回调后的操作逻辑
另外注意:在回调处理程序中调用SignInAsync后,当前请求的HttpContext.User不会立即更新。如果你在同一个请求里直接调用signInManager.IsSignedIn(HttpContext.User),会得到false。正确的做法是:
- 调用
SignInAsync后,跳转到另一个页面(比如主页) - 在跳转后的页面请求中,再检查
IsSignedIn状态
4. 验证Cookie是否正确生成
可以打开浏览器的开发者工具(F12),在Application标签下查看Cookie列表,确认是否存在名称为.AspNetCore.Identity.Application(对应Identity的Application Scheme)的Cookie,并且路径、过期时间等参数正常。
这样调整后,SignInManager就能正确识别用户的登录状态了。
内容的提问来源于stack exchange,提问作者Alex

