You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core部署在WAF/网关后Oracle OAuth认证异常问题

问题场景与故障现象

我有一个前端基于JavaScript、后端用C# .NET开发的应用,采用Oracle IDCS的OAuth协议做身份认证。原本运行正常,但现在后端部署在可访问公网的API网关/WAF之后:公网地址是public-host.com,网关会把公网请求转发到后端实际接收请求的内部地址private-host.io,导致后端“识别”的自身部署地址和实际公网地址不一致。

当前后端调用Oracle时,使用的OAuth参数redirect_uri是错误的,示例(未URL编码):
https://idcs-xxx.identity.oraclecloud.com/oauth2/v1/authorize?client_id=...&scope=...&...&redirect_uri=http://private-host.io/authorization_code/callback&...
公网用的是https,但内部地址用的是http。

尝试的修复代码

我尝试通过以下代码修改redirect_uri:

services
    .AddAuthentication(options =>
    {
        /*...*/
    })
    .AddOAuth("Oracle", options =>
    {
        options.Events = new OAuthEvents
        {
            OnRedirectToAuthorizationEndpoint = context =>
            {
                // 将context.RedirectUri中的redirect_uri参数替换为公网地址
                // 也就是把"http://internal-host.io/"替换成"https://public-host.com/"
                // context.RedirectUri是完整的重定向URL,比如:https://idcs-xxx.identity.oraclecloud.com/oauth2/v1/authorize?client_id=...&scope=...&...&redirect_uri=http://internal-host.io/authorization_code/callback
                // 这里是伪代码,实际需要处理URL编码问题
                context.RedirectUri = context.RedirectUri.Replace("http://internal-host.io/", "https://public-host.com/");
                context.Response.Redirect(context.RedirectUri);
                return Task.CompletedTask;
            }
        };
    });

修改后的错误

修改后,OAuth请求使用了正确的redirect_uri,Oracle认证成功并回调到正确地址https://public-host.com/authorization-code/callback?code=XXX,但C#代码抛出两个错误:

第一个错误:

An error was encountered while handling the remote login. Correlation failed.
Microsoft.AspNetCore.Authentication.AuthenticationFailureException:
   at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1+<HandleRequestAsync>d__12.MoveNext (Microsoft.AspNetCore.Authentication, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)

第二个错误:

Microsoft.AspNetCore.Authentication.AuthenticationFailureException: An error was encountered while handling the remote login.
---&gt; Microsoft.AspNetCore.Authentication.AuthenticationFailureException: OAuth token endpoint failure: invalid_redirect_uri;Description=Client XXXX requested an invalid redirect URL: http://internal-host.io:443/authorization-code/callback.

(注意错误中的http://internal-host.io)

我怀疑虽然在OnRedirectToAuthorizationEndpoint中修改了redirect_uri,但OAuth处理逻辑仍然期望使用内部地址,导致地址不一致引发失败。

补充配置信息

后端OAuth的基础配置如下:

services.AddAuthentication(options => {...}) 
.AddOAuth("Oracle", options =>
{
    Uri apiAddress = configuration.OracleApiAddress;
    options.AuthorizationEndpoint = $"{apiAddress}/oauth2/v1/authorize";
    options.Scope.Add("openid");
    options.Scope.Add("urn:opc:idm:__myscopes__");
    options.CallbackPath = new PathString("/authorization-code/callback");
    options.ClientId = configuration.OracleApplicationId;
    options.ClientSecret = configuration.OracleApplicationSecret;
    options.TokenEndpoint = $"{apiAddress}/oauth2/v1/token";
    options.UserInformationEndpoint = $"{apiAddress}/oauth2/v1/userinfo";
    // ...
}

解决方案

核心问题分析

问题出在两个关键环节:

  1. Token请求的redirect_uri不匹配:仅修改授权跳转时的redirect_uri无效,调用Token端点换取令牌时,后端仍用内部地址生成redirect_uri,导致Oracle IDCS校验失败。
  2. 关联Cookie不匹配:ASP.NET Core远程认证生成的关联Cookie包含内部地址,公网回调请求到达时,Cookie地址与实际请求地址不一致,触发Correlation failed错误。

具体修复步骤

1. 配置转发头识别真实请求地址(必做)

后端部署在网关后,需让ASP.NET Core从网关转发头中获取真实的公网协议和主机名。在Program.cs中添加以下配置:

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    // 开启转发头解析,获取真实协议和主机
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    // 添加网关的内部IP到信任列表,生产环境建议精准配置
    options.KnownProxies.Add(IPAddress.Parse("网关内部IP"));
    // 若网关是网段,可改用以下配置
    // options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("网关网段"), 24));
});

// 必须在UseRouting之前启用转发头解析
app.UseForwardedHeaders();
app.UseRouting();

配置后,ASP.NET Core会自动使用公网的https协议和public-host.com主机名生成redirect_uri,无需手动替换。

2. 强制Token请求使用公网redirect_uri(可选补充)

若转发头配置后仍存在Token校验问题,可在OAuth事件中强制指定Token请求的redirect_uri:

.AddOAuth("Oracle", options =>
{
    // 原有配置...
    options.Events = new OAuthEvents
    {
        OnTokenRequest = context =>
        {
            // 替换Token请求中的redirect_uri为公网地址
            context.Request.Parameters["redirect_uri"] = "https://public-host.com/authorization-code/callback";
            return Task.CompletedTask;
        }
    };
});

3. 验证关联Cookie生成逻辑

转发头配置生效后,关联Cookie会自动使用公网地址生成。若仍有Correlation failed错误,可手动指定回调地址:

.AddOAuth("Oracle", options =>
{
    // 原有配置...
    options.Events.OnRedirectToAuthorizationEndpoint = context =>
    {
        // 手动设置公网回调地址
        context.Properties.RedirectUri = "https://public-host.com/authorization-code/callback";
        // 重新组装授权URL
        var authorizationUrl = QueryHelpers.AddQueryString(
            options.AuthorizationEndpoint,
            new Dictionary<string, string>
            {
                ["client_id"] = options.ClientId,
                ["redirect_uri"] = context.Properties.RedirectUri,
                ["response_type"] = "code",
                ["scope"] = string.Join(" ", options.Scope),
                ["state"] = context.Properties.GetTokenValue("state"),
                ["nonce"] = context.Properties.GetTokenValue("nonce")
            });
        context.Response.Redirect(authorizationUrl);
        return Task.CompletedTask;
    };
});

额外注意事项

  • 确保Oracle IDCS的客户端配置中,已将https://public-host.com/authorization-code/callback添加到允许的重定向URI列表。
  • 网关必须正确转发X-Forwarded-Proto(值为https)和X-Forwarded-Host(值为public-host.com)请求头,否则转发头配置无法生效。

内容的提问来源于stack exchange,提问作者user1713059

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:53:12