fix: plain 401 for MCP OAuth discovery (#74)
* fix: return plain 401 for MCP OAuth discovery and harden auth flow - Return plain HTTP 401 with WWW-Authenticate header (no JSON-RPC body) so Claude Desktop's MCP client can trigger OAuth discovery correctly - Remove unused apiKey import from authorize route - Remove stale codeChallengeMethod parameter from oauth-codes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add Retry-After header to 429 rate limit response Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
5d66dd6bfc
commit
d61670231f
@@ -160,7 +160,6 @@ export async function POST(request: Request) {
|
||||
const redirectUri = url.searchParams.get('redirect_uri')
|
||||
const state = url.searchParams.get('state')
|
||||
const codeChallenge = url.searchParams.get('code_challenge') || ''
|
||||
const codeChallengeMethod = url.searchParams.get('code_challenge_method') || 'S256'
|
||||
|
||||
if (!redirectUri) {
|
||||
return NextResponse.json({ error: 'invalid_request' }, { status: 400 })
|
||||
@@ -193,7 +192,6 @@ export async function POST(request: Request) {
|
||||
const code = createAuthCode({
|
||||
userId: user.id,
|
||||
codeChallenge,
|
||||
codeChallengeMethod,
|
||||
redirectUri,
|
||||
})
|
||||
|
||||
|
||||
@@ -1234,21 +1234,25 @@ export async function handleMcpRequest(request: Request): Promise<Response> {
|
||||
|
||||
const token = extractBearerToken(request)
|
||||
if (!token) {
|
||||
return new Response(
|
||||
JSON.stringify(jsonRpcError(null, -32000, 'Authorization required')),
|
||||
{ status: 401, headers: { 'Content-Type': 'application/json', 'WWW-Authenticate': wwwAuth } }
|
||||
)
|
||||
return new Response('Unauthorized', {
|
||||
status: 401,
|
||||
headers: { 'WWW-Authenticate': wwwAuth },
|
||||
})
|
||||
}
|
||||
|
||||
const authResult = await validateApiKey(token)
|
||||
if ('error' in authResult) {
|
||||
const status = authResult.status
|
||||
const headers: Record<string, string> = { 'Content-Type': 'application/json' }
|
||||
if (status === 401) headers['WWW-Authenticate'] = wwwAuth
|
||||
return new Response(
|
||||
JSON.stringify(jsonRpcError(null, -32000, authResult.error)),
|
||||
{ status, headers }
|
||||
)
|
||||
if (status === 429) {
|
||||
return new Response(authResult.error, {
|
||||
status: 429,
|
||||
headers: { 'Content-Type': 'text/plain', 'Retry-After': '60' },
|
||||
})
|
||||
}
|
||||
return new Response('Unauthorized', {
|
||||
status: 401,
|
||||
headers: { 'WWW-Authenticate': wwwAuth },
|
||||
})
|
||||
}
|
||||
|
||||
const { userId } = authResult
|
||||
|
||||
@@ -21,7 +21,6 @@ function getEncryptionKey(): Buffer {
|
||||
export interface AuthCodePayload {
|
||||
userId: string
|
||||
codeChallenge: string
|
||||
codeChallengeMethod: string
|
||||
redirectUri: string
|
||||
exp: number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user