ASP.NET Core 5集成Okta时OpenIdConnect重定向用HTTP而非HTTPS问题
该问题由反向代理HTTPS卸载场景下的请求协议识别错误导致:当前部署架构中AWS ALB负责终止HTTPS连接,通过HTTP协议将请求转发给运行在容器内的ASP.NET Core应用,应用默认仅根据当前收到的请求生成跳转地址,无法感知前端用户实际是通过HTTPS访问,因此生成OIDC授权请求时自动将redirect_uri拼接为HTTP前缀,和Okta后台配置的HTTPS回调地址不匹配触发400错误。
若强行在Okta后台添加HTTP回调地址,会触发两类问题:一是浏览器识别到认证信息通过HTTP提交弹出不安全提示,二是现有配置中已设置Cookie的SecurePolicy为Always,HTTP请求下浏览器不会回传存储在Cookie中的state、nonce校验值,最终触发message.State is null or empty的认证异常。
1. 配置转发头中间件,让应用正确识别原始请求信息
ASP.NET Core提供了转发头中间件用于处理反向代理场景,需要将该中间件放在所有其他中间件之前执行,确保后续所有组件都能拿到正确的请求协议、客户端IP信息。
修改Configure方法,在最开头添加如下配置:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 优先配置转发头,适配ALB HTTPS卸载场景 var forwardedHeadersOptions = new ForwardedHeadersOptions { ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto }; // 清除默认的本地代理IP限制,信任ALB转发的头信息 forwardedHeadersOptions.KnownNetworks.Clear(); forwardedHeadersOptions.KnownProxies.Clear(); app.UseForwardedHeaders(forwardedHeadersOptions); // 原有逻辑保持不变 if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
配置完成后,应用会自动读取ALB转发请求时携带的X-Forwarded-Proto: https头,将当前请求的协议识别为HTTPS,自动生成HTTPS前缀的回调地址。
注意:不要在该部署架构下添加app.UseHttpsRedirection()中间件,否则会导致ALB回源请求被强制重定向到HTTPS,触发访问死循环。
2. 补全Cookie安全配置
当前仅配置了Nonce和Correlation Cookie的安全策略,需要补全主认证Cookie的安全配置,避免跨场景下的Cookie丢失问题。修改ConfigureServices中的Cookie认证配置:
.AddCookie(options => { options.Cookie.SameSite = SameSiteMode.Lax; // 生产环境始终通过HTTPS传输认证Cookie options.Cookie.SecurePolicy = CookieSecurePolicy.Always; })
3. 兜底配置(可选,推荐生产环境添加)
如果担心转发头配置受环境影响失效,可以在OpenID Connect配置中添加事件逻辑,强制将回调地址重写为HTTPS格式,彻底避免HTTP前缀问题:
.AddOpenIdConnect(options => { // 原有配置保持不变 options.NonceCookie.SecurePolicy = CookieSecurePolicy.Always; options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always; options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.Authority = oktaOrgUri; options.RequireHttpsMetadata = true; options.ClientId = oktaClientId; options.ClientSecret = oktaClientSecret; options.ResponseType = OpenIdConnectResponseType.Code; options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("email"); options.SaveTokens = true; options.TokenValidationParameters = new TokenValidationParameters { IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(oktaClientSecret)), NameClaimType = "name", RoleClaimType = "groups", ValidateIssuer = true }; // 新增兜底回调地址重写逻辑 options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = context => { var redirectUriBuilder = new UriBuilder(context.ProtocolMessage.RedirectUri) { Scheme = Uri.UriSchemeHttps, Port = -1 // 不显式指定端口,避免端口号出现在回调地址中导致匹配失败 }; context.ProtocolMessage.RedirectUri = redirectUriBuilder.Uri.ToString(); return Task.CompletedTask; } }; });
4. 两侧配置校验
- ALB侧:确认转发规则未删除
X-Forwarded-Proto、X-Forwarded-For头,AWS ALB默认会自动携带这两个头,无特殊修改无需额外调整。 - Okta后台:删除所有HTTP类型的登录重定向URI,仅保留
https://exampleapp.companyname.com/signin-oidc即可。
完成以上配置后重启容器,授权跳转时会自动生成正确的HTTPS回调地址,不会再出现400错误、不安全提示和State为空的异常。
内容的提问来源于stack exchange,提问作者MateoSkyline

