Skip to content

Commit ea1f8c7

Browse files
feat: seperate credential extraction into a method
1 parent cc4a70f commit ea1f8c7

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

‎src/mcp/server/auth/middleware/client_auth.py‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,49 @@ async def authenticate_request(self, request: Request) -> OAuthClientInformation
121121
raise AuthenticationError("Client secret has expired") # pragma: no cover
122122

123123
return client
124+
125+
async def _get_credentials(self, request: Request) -> ClientCredentials:
126+
"""
127+
Extract client credentials from request, either from form data or Basic auth header.
128+
129+
Basic auth header takes precedence over form data.
130+
131+
Args:
132+
request: The HTTP request containing client credentials
133+
Returns:
134+
The extracted client credentials
135+
"""
136+
# First, check for Basic auth header
137+
auth_header = request.headers.get("Authorization", "")
138+
if auth_header.startswith("Basic "):
139+
try:
140+
encoded_credentials = auth_header[6:] # Remove "Basic " prefix
141+
decoded = base64.b64decode(encoded_credentials).decode("utf-8")
142+
if ":" not in decoded:
143+
raise ValueError("Invalid Basic auth format")
144+
client_id, client_secret = decoded.split(":", 1)
145+
146+
# URL-decode the client_id per RFC 6749 Section 2.3.1
147+
client_id = unquote(client_id)
148+
client_secret = unquote(client_secret)
149+
return ClientCredentials(
150+
auth_method="client_secret_basic",
151+
client_id=client_id,
152+
client_secret=client_secret,
153+
)
154+
except (ValueError, UnicodeDecodeError, binascii.Error):
155+
raise AuthenticationError("Invalid Basic authentication header")
156+
157+
# If not, check for client_id and client_secret in form data
158+
form_data = await request.form()
159+
client_id = form_data.get("client_id")
160+
if not client_id:
161+
raise AuthenticationError("Missing client_id")
162+
163+
raw_client_secret = form_data.get("client_secret")
164+
client_secret = str(raw_client_secret) if isinstance(raw_client_secret, str) else None
165+
return ClientCredentials(
166+
auth_method="client_secret_post",
167+
client_id=str(client_id),
168+
client_secret=client_secret,
169+
)

0 commit comments

Comments
 (0)