集成Azure AD到ASP.NET Core Identity时GetExternalLoginInfoAsync始终返回null
问题解决办法
注:你当前的中间件管道顺序(
UseAuthentication在UseAuthorization之前)符合要求,无需调整。
一、GetExternalLoginInfoAsync 返回null的修复方案
- 修正身份验证方案配置
你当前使用的AddMicrosoftIdentityWebApp默认会用独立的Cookie存储身份信息,而GetExternalLoginInfoAsync只能读取Identity体系专属的Identity.External方案的Cookie数据,因此需要调整配置指定SignInScheme:
services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<IdentityContext>() .AddDefaultTokenProviders(); // 修改身份验证配置,指定用Identity的外部登录方案存储认证信息 services.AddAuthentication() .AddMicrosoftIdentityWebApp( Configuration.GetSection("AzureAd"), OpenIdConnectDefaults.AuthenticationScheme, IdentityConstants.ExternalScheme ); services.AddControllersWithViews(); services.AddRazorPages() .AddMicrosoftIdentityUI();
- 检查Azure AD应用配置
- 进入Azure门户的应用注册页面,在「身份验证」-「隐式授权和混合流」中,勾选ID令牌选项
- 确认Azure后台配置的回调地址和代码中回调地址完全一致,包括协议、域名、端口、路径
- 确认配置的Scope包含
openid、profile、email三个基础权限
- 确认声明映射配置
如果做了自定义声明映射,需确保NameIdentifier(对应sub/oid声明)没有被移除,该字段是GetExternalLoginInfoAsync识别用户的必填字段。
二、硬编码添加loginProvider的实现
可以手动构造ExternalLoginInfo对象,仅建议在调试或者确认身份验证逻辑安全的场景下使用:
[HttpGet] public async Task<IActionResult> ExternalLoginCallback() { var info = await _signInManager.GetExternalLoginInfoAsync().ConfigureAwait(false); // 硬编码补充逻辑 if (info == null && User.Identity?.IsAuthenticated == true) { // 从已验证的用户声明中提取必填字段 var providerKey = User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("oid") ?? User.FindFirstValue("sub"); if (!string.IsNullOrEmpty(providerKey)) { info = new ExternalLoginInfo( principal: User, loginProvider: OpenIdConnectDefaults.AuthenticationScheme, providerKey: providerKey, displayName: "Azure AD" ); } } if (info == null) { // 身份验证失败的处理逻辑 return RedirectToAction("Login"); } var result = await _signInManager.ExternalLoginSignInAsync( info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: false) .ConfigureAwait(false); //其他代码 }
注意:该方式跳过了Identity的外部信息校验逻辑,需要自行验证用户身份的合法性,避免出现安全漏洞。
内容的提问来源于stack exchange,提问作者Chmelya
相关产品推荐
相关产品推荐

