Skip to content

[bug] Current AspNetCore integration does not correctly track client context when behind proxies that use X-Forwarded-* headers #2231

Open
@DrEsteban

Description

@DrEsteban

Component

OpenTelemetry.Instrumentation.AspNetCore

Package Version

Package Name Version
Azure.Monitor.OpenTelemetry.AspNetCore 1.3.0-beta.2
OpenTelemetry.Exporter.Console 1.9.0
OpenTelemetry.Instrumentation.AspNetCore (transitive) 1.9.0

Runtime Version

net8.0

Description

Because the current AspNetCore integration sets all request telemetry in the OnStart() method, it does not work correctly in situations where the webapp is receiving traffic behind a proxy where X-Forwarded-*-type headers are being used to forward the original ClientIP, Scheme, Path, etc.

ASP.NET includes middleware that by default will recognize:

  • X-Forwarded-For (original clientIP)
  • X-Forwarded-Host (original Host header)
  • X-Forwarded-Proto (HTTP vs HTTPS)
  • X-Forwarded-Prefix (original base path - for proxies that rewrite paths when forwarding to backend)

In my case, I am running an ASP.NET8.0 app in Azure WebApps for Linux, which terminates TLS and forwards client context via headers like X-Forwarded-For, X-Forwarded-Proto, etc. I am using the Forwarded Headers Middleware to propagate those headers to the HttpContext, (which I've verified is working), but the OpenTelemetry framework is still using the original values when publishing telemetry.

Compare this with the native Application Insights SDK. If I configure OpenTelemetry and Application Insights side-by-side, sending to the same Application Insights resource, here are the request logs I see on the Azure portal:
Screenshot 2024-10-20 223114-2
As expected, there are 2 copies of each request because I'm double-logging traces with 2 frameworks. However, the OpenTelemetry version has not correctly recognized that the original client connection was over HTTPS, whereas the ApplicationInsights one has.

I believe this is because these values change after the "Activity" is started, once the Forwarded Headers Middleware kicks in. But by that time the Activity has already been created with the original values. Therefore, it would seem the only way to support that scenario would be to set/reset these values from the HttpContext in the OnStop() method as well. (Or by some other fancier means of tying into ASP.NET Core's middleware pipeline...)

Steps to Reproduce

  1. Create a standard ASP.NET8.0 app with the Azure.Monitor.OpenTelemetry.AspNetCore OpenTelemetry distro and the native Microsoft.ApplicationInsights.AspNetCore SDK:
    e.g.
    builder.Services.AddOpenTelemetry().UseAzureMonitor(); // Configures `AspNetCoreInstrumentation`
    builder.Services.AddApplicationInsightsTelemetry();
  2. Provision Application Insights and Azure WebApps/AppService instances in Azure.
  3. Configure APPLICATIONINSIGHTS_CONNECTION_STRING appropriately
  4. Deploy .NET app to WebApp, and make a few requests, ensuring you are using HTTPS
    • Azure WebApps will automatically add the X-Forwarded-* headers when it terminates TLS and forwards the requests to your app
  5. Open Application Insights instance > Logs tab > requests table

UPDATE: Added a comment where I provided a localhost repro: link

Expected Result

I expect to see both log messages are mostly identical, at least w.r.t. basic properties like request URL and ClientIP/Client Location.

Actual Result

Application Insights-generated log is correct, but OpenTelemetry-generated log as incorrect Scheme and ClientIP/Client Location.

Additional Context

This is somewhat related to #1786.

This has also been logged in Microsoft's distro (link), but was deemed to be a defect in the underlying SDK OpenTelemetry.Instrumentation.AspNetCore and therefore closed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcomp:instrumentation.aspnetcoreThings related to OpenTelemetry.Instrumentation.AspNetCore

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions