Skip to content

Conversation

@vukelich
Copy link
Member

@vukelich vukelich commented Dec 1, 2025

What does this PR do?

Fixes the remote MCP server being called by VS Code.

Fix OAuth Protected Resource Metadata flows with AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS. This configuration will read the X-Forwarded-Proto request header sent from Azure Container Apps to construct the URLs needed for OAuth PRM within the original claims challenge and the PRM endpoint's JSON body.

GitHub issue number?

#1214

Pre-merge Checklist

  • Required for All PRs
    • Read contribution guidelines
    • PR title clearly describes the change
    • Commit history is clean with descriptive messages (cleanup guide)
    • Added comprehensive tests for new/modified functionality
    • Updated servers/Azure.Mcp.Server/CHANGELOG.md and/or servers/Fabric.Mcp.Server/CHANGELOG.md for product changes (features, bug fixes, UI/UX, updated dependencies)
  • For MCP tool changes:
    • One tool per PR: This PR adds or modifies only one MCP tool for faster review cycles
    • Updated servers/Azure.Mcp.Server/README.md and/or servers/Fabric.Mcp.Server/README.md documentation
    • Validate README.md changes using script at eng/scripts/Process-PackageReadMe.ps1. See Package README
    • Updated command list in /servers/Azure.Mcp.Server/docs/azmcp-commands.md and/or /docs/fabric-commands.md
    • Run .\eng\scripts\Update-AzCommandsMetadata.ps1 to update tool metadata in azmcp-commands.md (required for CI)
    • For new or modified tool descriptions, ran ToolDescriptionEvaluator and obtained a score of 0.4 or more and a top 3 ranking for all related test prompts
    • For tools with new names, including new tools or renamed tools, update consolidated-tools.json
    • For new tools associated with Azure services or publicly available tools/APIs/products, add URL to documentation in the PR description
  • Extra steps for Azure MCP Server tool changes:
    • Updated test prompts in /servers/Azure.Mcp.Server/docs/e2eTestPrompts.md
    • 👉 For Community (non-Microsoft team member) PRs:
      • Security review: Reviewed code for security vulnerabilities, malicious code, or suspicious activities before running tests (crypto mining, spam, data exfiltration, etc.)
      • Manual tests run: added comment /azp run mcp - pullrequest - live to run Live Test Pipeline

…Y_ENABLE_FORWARDED_HEADERS. This configuration will read the X-Forwarded-Proto request header sent from Azure Container Apps to construct the URLs needed for OAuth PRM within the original claims challenge and the PRM endpoint's JSON body.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes OAuth Protected Resource Metadata flows when using forwarded headers in Azure Container Apps environments. The fix addresses an issue where the OAuth metadata URLs were incorrectly using the internal HTTP scheme instead of the external HTTPS scheme that clients use.

Key Changes

  • Added environment variable AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS to opt-in to using X-Forwarded-Proto header
  • Introduced GetSchemeForOAuthProtectedResourceMetadata local function to determine the correct scheme for OAuth URLs
  • Applied the fix to both the WWW-Authenticate challenge response and the OAuth protected resource metadata endpoint

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

using System.CommandLine.Parsing;
using System.Diagnostics;
using System.Net;
using Azure.Core;
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The using Azure.Core; directive appears to be unused. The only reference to Azure.Core in the file is a string literal comparison ("Azure.Core.Http") at line 872, which doesn't require this import.

Suggested change
using Azure.Core;

Copilot uses AI. Check for mistakes.
Comment on lines +560 to +602
string GetSchemeForOAuthProtectedResourceMetadata(HttpRequest request)
{
string scheme = request.Scheme;

// Default to "false" for enabling forwarded headers. The env var must be present,
// and it must be parsed to "true".
bool enableForwardedHeaders =
bool.TryParse(
Environment.GetEnvironmentVariable("AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS"),
out bool parsedEnvVar)
&& parsedEnvVar;

// Azure Container Apps setups usually use HTTP between the ACA platform's
// reverse proxy and the application container. Our OAuth claims challenge
// needs to match what the client will use as a scheme. So only in this
// case do we use the X-Forwarded-Proto header if present. We're also going
// to limit specifically to "http" and "https" values and use their
// lowercase forms rather than the casing in the header.
//
// Other reverse proxies or load balancers may also use X-Forwarded-Proto or
// may use something different. We only special case ACA here because it's
// part of the samples as of 2.0-beta.5. More thorough logic and any
// configuration options can be added later if needed, and that could use
// ASP.NET Core's Forwarded Headers Middleware. See:
// https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer
if (enableForwardedHeaders
&& request.Headers.TryGetValue("X-Forwarded-Proto", out StringValues forwardedProto))
{
if (forwardedProto.FirstOrDefault() is string forwardedProtoValue)
{
if (string.Equals(forwardedProtoValue, "https", StringComparison.OrdinalIgnoreCase))
{
scheme = "https";
}
else if (string.Equals(forwardedProtoValue, "http", StringComparison.OrdinalIgnoreCase))
{
scheme = "http";
}
}
}

return scheme;
}
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new GetSchemeForOAuthProtectedResourceMetadata local function lacks test coverage. Given that this file has comprehensive unit tests in ServiceStartCommandTests.cs, consider adding tests to cover:

  • Default behavior when AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS is not set
  • Behavior when the environment variable is set to true and X-Forwarded-Proto header is present with various values (https, http, HTTPS, HTTP, invalid values)
  • Behavior when the environment variable is set to false but the header is present
  • Behavior when the environment variable is set but the header is missing

Copilot uses AI. Check for mistakes.
Comment on lines +585 to +599
if (enableForwardedHeaders
&& request.Headers.TryGetValue("X-Forwarded-Proto", out StringValues forwardedProto))
{
if (forwardedProto.FirstOrDefault() is string forwardedProtoValue)
{
if (string.Equals(forwardedProtoValue, "https", StringComparison.OrdinalIgnoreCase))
{
scheme = "https";
}
else if (string.Equals(forwardedProtoValue, "http", StringComparison.OrdinalIgnoreCase))
{
scheme = "http";
}
}
}
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 'if' statements can be combined.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

2 participants