fix: use X-MCP-Proxy-Auth header for proxy authentication
Changed proxy authentication to use a custom header (X-MCP-Proxy-Auth) instead of the standard Authorization header. This prevents conflicts when the proxy needs to forward the client's Authorization header to upstream MCP servers. - Updated client to send proxy auth token in X-MCP-Proxy-Auth header - Updated server auth middleware to check X-MCP-Proxy-Auth header - Applies to all transport types (SSE, stdio, streamable-http) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
65910ebc4c
commit
fdae89ecbf
2 changed files with 12 additions and 6 deletions
|
|
@ -246,7 +246,7 @@ export function useConnection({
|
||||||
const proxyAuthToken = getMCPProxyAuthToken(config);
|
const proxyAuthToken = getMCPProxyAuthToken(config);
|
||||||
const headers: HeadersInit = {};
|
const headers: HeadersInit = {};
|
||||||
if (proxyAuthToken) {
|
if (proxyAuthToken) {
|
||||||
headers["Authorization"] = `Bearer ${proxyAuthToken}`;
|
headers["X-MCP-Proxy-Auth"] = `Bearer ${proxyAuthToken}`;
|
||||||
}
|
}
|
||||||
const proxyHealthResponse = await fetch(proxyHealthUrl, { headers });
|
const proxyHealthResponse = await fetch(proxyHealthUrl, { headers });
|
||||||
const proxyHealth = await proxyHealthResponse.json();
|
const proxyHealth = await proxyHealthResponse.json();
|
||||||
|
|
@ -335,7 +335,7 @@ export function useConnection({
|
||||||
const proxyAuthToken = getMCPProxyAuthToken(config);
|
const proxyAuthToken = getMCPProxyAuthToken(config);
|
||||||
const proxyHeaders: HeadersInit = {};
|
const proxyHeaders: HeadersInit = {};
|
||||||
if (proxyAuthToken) {
|
if (proxyAuthToken) {
|
||||||
proxyHeaders["Authorization"] = `Bearer ${proxyAuthToken}`;
|
proxyHeaders["X-MCP-Proxy-Auth"] = `Bearer ${proxyAuthToken}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create appropriate transport
|
// Create appropriate transport
|
||||||
|
|
|
||||||
|
|
@ -138,13 +138,17 @@ const authMiddleware = (
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers["x-mcp-proxy-auth"];
|
||||||
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
const authHeaderValue = Array.isArray(authHeader)
|
||||||
|
? authHeader[0]
|
||||||
|
: authHeader;
|
||||||
|
|
||||||
|
if (!authHeaderValue || !authHeaderValue.startsWith("Bearer ")) {
|
||||||
sendUnauthorized();
|
sendUnauthorized();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const providedToken = authHeader.substring(7); // Remove 'Bearer ' prefix
|
const providedToken = authHeaderValue.substring(7); // Remove 'Bearer ' prefix
|
||||||
const expectedToken = sessionToken;
|
const expectedToken = sessionToken;
|
||||||
|
|
||||||
// Convert to buffers for timing-safe comparison
|
// Convert to buffers for timing-safe comparison
|
||||||
|
|
@ -196,7 +200,9 @@ const createTransport = async (req: express.Request): Promise<Transport> => {
|
||||||
|
|
||||||
const headers = getHttpHeaders(req, transportType);
|
const headers = getHttpHeaders(req, transportType);
|
||||||
|
|
||||||
console.log(`SSE transport: url=${url}, headers=${Object.keys(headers)}`);
|
console.log(
|
||||||
|
`SSE transport: url=${url}, headers=${JSON.stringify(headers)}`,
|
||||||
|
);
|
||||||
|
|
||||||
const transport = new SSEClientTransport(new URL(url), {
|
const transport = new SSEClientTransport(new URL(url), {
|
||||||
eventSourceInit: {
|
eventSourceInit: {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue