ASP.NET Core MVC调用MSGraph令牌过期后遇OpenIdConnect认证错误
问题核心
本地调试时,ASP.NET Core MVC应用通过Microsoft.Identity.Web实现的代表用户授权流能正常刷新令牌并重定向登录,但部署到Azure App Service后,令牌过期触发登录重定向时出现以下错误:
InvalidOperationException: No authentication handler is registered for the scheme 'OpenIdConnect'. The registered schemes are: AppServicesAuthentication. Did you forget to call AddAuthentication().AddSomeAuthHandler?
Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties).
根因
Azure App Service默认启用的**App Service Authentication(俗称Easy Auth)**会自动注册AppServicesAuthentication认证方案,并覆盖应用代码中配置的默认认证方案优先级。当令牌过期触发ChallengeAsync时,系统找不到你代码中配置的OpenIdConnect处理器,因为Easy Auth的中间件已经接管了认证流程。
解决方案
1. 禁用App Service内置认证(Easy Auth)
这是最直接的解决方式,因为你的应用已经通过Microsoft.Identity.Web自行实现了完整的认证逻辑:
- 登录Azure门户,进入目标App Service实例
- 左侧导航栏选择「认证」
- 将「启用认证」开关设置为「关闭」
- 保存配置并重启App Service
2. 确保认证中间件顺序正确
在Startup.cs或Program.cs的Configure方法中,必须保证UseAuthentication在UseAuthorization之前执行:
app.UseAuthentication(); app.UseAuthorization(); // 其他中间件(如UseMvc、UseEndpoints等)放在后面
3. 显式指定Challenge使用的认证方案(可选,若需保留Easy Auth)
如果因业务需求必须保留App Service Easy Auth,可在触发登录重定向时显式指定使用OpenIdConnect方案:
- 在需要授权的Controller/Action上指定认证方案:
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] public class HomeController : Controller { // ... } - 或在令牌过期的自定义处理逻辑中,显式调用指定scheme的Challenge:
await HttpContext.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = Request.Path });
4. 清理App Service应用设置
检查App Service的「配置」->「应用程序设置」,确保不存在以下强制开启Easy Auth的设置:
- 若存在
WEBSITE_AUTH_ENABLED,将其值改为false - 移除所有与App Service认证相关的自动生成设置(如
WEBSITE_AUTH_AAD_CLIENT_ID等)
验证步骤
- 部署修改后的应用到App Service
- 等待令牌过期后触发登录流程,确认错误不再出现
- 查看App Service日志,确认认证中间件加载正常
内容的提问来源于stack exchange,提问作者user28164231

