.NET Core Web应用集成Microsoft Graph(OpenIdConnect+Identity)报错求助
解决Microsoft Graph集成中的MsalUiRequiredException问题
问题根源
错误提示No account or login hint was passed to the AcquireTokenSilent call的核心原因:
- 本地Identity系统与Microsoft Identity Web的令牌缓存未正确关联,AcquireTokenSilent无法找到当前用户对应的账户信息
- 登录流程中,外部登录的令牌未正确持久化到本地用户的身份上下文
- OpenIdConnect配置中的SignInScheme设置错误,导致身份验证会话未绑定到本地用户
具体修复步骤
1. 修正OpenIdConnect的SignInScheme配置
在Startup的Configure<OpenIdConnectOptions>中,将SignInScheme改为IdentityConstants.ApplicationScheme,确保Microsoft登录结果关联到本地应用的身份会话:
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options => { options.SignInScheme = IdentityConstants.ApplicationScheme; // 替换原ExternalScheme options.SaveTokens = true; options.Authority = Configuration["Authentication:Microsoft:OAuth"]; options.MetadataAddress = Configuration["Authentication:Microsoft:Meta"]; });
2. 完善ExternalLoginCallback中的令牌持久化逻辑
在ExternalLoginCallback中,无论用户是已有账户还是首次登录,都要确保外部令牌被正确保存到本地用户上下文:
var info = await _signInManager.GetExternalLoginInfoAsync(); if (info == null) { _accountProvider.LogInformation(new LoginLog { Message = $"Failed in getting GetExternalLoginInfoAsync()", MethodName = "ExternalLoginCallback", MethodType = "GET", ReturnURL = returnUrl, Success = false, }); return RedirectToAction(nameof(Login)); } var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: true, bypassTwoFactor: true); if (result.Succeeded) { // 已有用户:更新并持久化外部令牌 await _signInManager.UpdateExternalAuthenticationTokensAsync(info); // 后续跳转逻辑 } else { // 首次登录:创建本地用户并关联外部登录 var email = info.Principal.FindFirstValue(ClaimTypes.Email); var user = new ApplicationUser { UserName = email, Email = email }; var createResult = await _userManager.CreateAsync(user); if (createResult.Succeeded) { createResult = await _userManager.AddLoginAsync(user, info); if (createResult.Succeeded) { await _signInManager.UpdateExternalAuthenticationTokensAsync(info); await _signInManager.SignInAsync(user, isPersistent: true); // 后续跳转逻辑 } } // 错误处理逻辑 }
关键:必须在用户登录成功后调用
UpdateExternalAuthenticationTokensAsync,确保Microsoft的令牌被保存到本地用户的身份存储中。
3. 调整Microsoft Graph的调用方式
调用Graph时无需手动指定WithAuthenticationScheme,Microsoft Identity Web已集成令牌自动获取逻辑,直接使用注入的GraphServiceClient即可:
// 移除WithAuthenticationScheme,直接调用 var currentUser = await _graphServiceClient.Me.Request().GetAsync();
4. 检查配置文件中的权限范围
确认DownstreamApi:Scopes包含Microsoft Graph所需权限,例如:
"DownstreamApi": { "Scopes": "User.Read Sites.Read.All", "BaseUrl": "https://graph.microsoft.com/v1.0" }
验证流程
- 重启应用,使用Microsoft账户登录
- 调用Graph接口,确认不再抛出MsalUiRequiredException
- 可通过
HttpContext.GetTokenAsync("access_token")验证是否能获取有效令牌
内容的提问来源于stack exchange,提问作者Andrew Casey
相关产品推荐
相关产品推荐

