.NET 5应用使用Microsoft登录时如何正确设置redirect URI?
问题原因
该问题由EKS反向代理层的SSL卸载机制导致:用户访问全程走HTTPS协议,但负载均衡/Ingress转发请求到应用容器时使用HTTP协议,ASP.NET Core默认不会读取反向代理携带的X-Forwarded-Proto原始协议头,因此生成微软登录的重定向地址时自动使用了HTTP协议,和Azure AD后台配置的HTTPS回调地址不匹配导致报错。
代码修改方案
第一步:修改ConfigureServices方法
添加转发头配置,同时给微软身份验证组件添加重定向地址修正逻辑:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var configSettings = new ConfigSettings(); Configuration.Bind("ConfigSettings", configSettings); services.AddSingleton(configSettings); services.AddSingleton<IAuthResponseFactory, AuthResponseFactory>(); // 新增:配置反向代理转发头,识别原始请求的协议和IP services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // 生产环境建议指定你的EKS集群代理的IP段,这里为了适配所有环境先清空限制 options.KnownNetworks.Clear(); options.KnownProxies.Clear(); }); services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(options => { Configuration.Bind("AzureAd", options); // 新增:重写重定向逻辑,强制使用HTTPS协议 options.Events.OnRedirectToIdentityProvider = context => { if (context.ProtocolMessage.RedirectUri.StartsWith("http://")) { context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http://", "https://"); } return Task.CompletedTask; }; }); services.AddControllersWithViews(options => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); options.Filters.Add(new AuthorizeFilter(policy)); }); services.AddRazorPages() .AddMicrosoftIdentityUI(); services.AddHealthChecks(); services.Configure<HealthCheckPublisherOptions>(options => { options.Delay = TimeSpan.FromSeconds(2); options.Predicate = (check) => check.Tags.Contains("ready"); }); }
第二步:修改Configure方法的中间件顺序
必须在所有中间件最开头添加转发头处理中间件,才能让后续逻辑拿到正确的原始请求信息:
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 新增:放在所有中间件最前面 app.UseForwardedHeaders(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapRazorPages(); }); app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions() { Predicate = (check) => check.Tags.Contains("ready") }); endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()); }); }
可选优化
如果你的部署地址固定,也可以直接把完整重定向地址写到配置文件里,替换上面的动态替换逻辑即可:
options.Events.OnRedirectToIdentityProvider = context => { context.ProtocolMessage.RedirectUri = "https://你的正式域名/signin-oidc"; return Task.CompletedTask; };
内容的提问来源于stack exchange,提问作者Daan
相关产品推荐
相关产品推荐

