Asp.Net Core多认证集成Azure AD:GetExternalLoginInfoAsync返回空值
解决GetExternalLoginInfoAsync()返回null的问题
问题根源
- PolicyScheme转发逻辑错误:你的
JWT_OR_COOKIE策略中,将非Bearer头的请求全部转发到OpenIdConnectDefaults.AuthenticationScheme,但外部登录回调请求需要读取Cookie中存储的临时外部登录信息,应该使用CookieAuthenticationDefaults.AuthenticationScheme处理。 - SignInManager依赖Cookie认证:
GetExternalLoginInfoAsync()需要从Cookie中获取外部登录流程中存储的临时数据,若请求未通过Cookie认证,就无法读取这些数据,导致返回null。
解决方案
1. 修正PolicyScheme的转发逻辑
将非Bearer请求的转发目标改为Cookie认证方案,确保回调请求能正确读取Cookie中的外部登录信息:
.AddPolicyScheme("JWT_OR_COOKIE", "JWT_OR_COOKIE", options => { options.ForwardDefaultSelector = context => { string authorization = context.Request.Headers[HeaderNames.Authorization]; if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer ")) return JwtBearerDefaults.AuthenticationScheme; // 非Bearer请求使用Cookie认证,而非OpenIdConnect return CookieAuthenticationDefaults.AuthenticationScheme; }; });
2. (可选)强制回调接口使用Cookie认证
在ExternalLoginCallback方法上添加特性,明确指定使用Cookie认证方案,避免全局策略的影响:
[HttpGet] [AllowAnonymous] [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] public async Task<IActionResult> ExternalLoginCallback(string returnUrl) { var acccessToken = await HttpContext.GetTokenAsync("access_token"); var info = await _signInManager.GetExternalLoginInfoAsync(); if (info == null) { // 可添加错误处理逻辑 return BadRequest("无法获取外部登录信息"); } var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false); if (result.Succeeded) { await _signInManager.UpdateExternalAuthenticationTokensAsync(info); return LocalRedirect(returnUrl); } else { return Ok(); } }
补充说明
- OpenIdConnect的
SignInScheme已正确设置为Cookie方案,无需修改。 SaveTokens=true确保令牌被存储在Cookie中,这部分配置没问题。
内容的提问来源于stack exchange,提问作者Hoang Minh
相关产品推荐
相关产品推荐

