.NET 8 WsFederation反向代理环境下302跳转本地域名问题排查
问题:.NET 8 WsFederation应用在反向代理环境下302重定向异常
我有一个使用WsFederation的.NET 8.0应用,同一套二进制文件和配置在一台服务器上运行正常,另一台却完全异常。
正常服务器登录时,应用端点返回的ChallengeResult会生成指向login.microsoftonline.com/[租户ID]/wsfed?[查询字符串]的302响应;异常服务器生成的302则指向[自有域名]/[租户ID]/[其余内容]。
两台服务器均具备互联网访问权限,且都能访问AAD配置的MetadataAddress。异常服务器部署在两层反向代理后:第一层是公共网关,通过URL Rewrite规则指向应用服务器;应用服务器使用IIS服务器场将请求路由至各进程。我尝试在服务器场重写规则中设置X-Forwarded-Host和HTTP_HOST,但未生效。
认证配置代码
services.AddAuthentication() .AddWsFederation(options => { // MetadataAddress represents the Active Directory instance used to authenticate users. options.MetadataAddress = Configuration["AAD:MetadataAddress"]; options.Wtrealm = Configuration["AAD:Wtrealm"]; options.Wreply = Configuration["AAD:Wreply"]; options.CallbackPath = new PathString("/signin-wsfed"); options.AllowUnsolicitedLogins = true; }) .AddCookie(options => { options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; options.Cookie.IsEssential = true; options.Cookie.SameSite = SameSiteMode.Lax; });
登录端点代码
[AllowAnonymous] public IActionResult InternalLogin([FromQuery(Name = "returnUrl")] string returnUrl = null) { try { string provider = "WsFederation"; var redirectUrl = Url.Action(nameof(InternalLoginCallback), "UserAccount", new { ReturnUrl = returnUrl }); var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); _logService.LogInternalSignInRequest(); using var log = new LoggerConfiguration().WriteTo.File("logs/serilog.txt").CreateLogger(); // The following always displays the name of the server farm, despite best efforts to set the Host (and X-Forwarded-Host) header myself log.Information("DURING INTERNAL LOGIN, provider: {p}, redirect URL: {u}, properties: {pt}", provider, redirectUrl, properties); return new ChallengeResult(provider, properties); } catch (Exception e) { return BadRequest("Failed"); } }
我预期ChallengeResult在两台服务器上生成相同的302响应,即指向login.microsoftonline.com,这与元数据接口返回的指定一致。由于本地与两台服务器获取的元数据结果相同,我认为Host标头与此无关。是什么原因导致流程将302重定向到本地地址而非元数据中的IDP?
编辑:问题已解决
问题关键
- 登录流程依赖302重定向到IDP;
- 应用请求路由(ARR)作为一线反向代理。
排查步骤:记录应用实际返回的302
我曾误以为浏览器收到的302是应用直接返回的,后来通过自定义中间件记录应用实际输出的Location标头,证实相同输入下应用返回的结果一致,问题出在下游的ARR。
自定义重定向日志中间件代码
public class RedirectLoggingMiddleware { private readonly RequestDelegate _next; private readonly Logger _logger; public RedirectLoggingMiddleware(RequestDelegate next, ILogger<RedirectLoggingMiddleware> logger) { _next = next; // I'm really starting to like Serilog! _logger = new Serilog.LoggerConfiguration().WriteTo.Console().CreateLogger(); } public async Task Invoke(HttpContext context) { await _next(context); // Call the next middleware if (context.Response.StatusCode == 302) { // Log the redirect var location = context.Response.Headers["Location"].ToString(); _logger.Information("302 Redirect to {Location} from {Path}", location, context.Request.Path); } } }
中间件注册代码(Startup.cs)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // Register your middleware early in the pipeline app.UseMiddleware<RedirectLoggingMiddleware>(); // ... other middleware registrations }
内容的提问来源于stack exchange,提问作者BobRz
相关产品推荐
相关产品推荐

