Skip to content

Commit 6f5622c

Browse files
Fix remaining CodeRabbit review issues for Keycloak provider
Address 3 additional code review comments from CodeRabbitAI: - Fix markdownlint violations in keycloak/README.md: - Add bash language tag to docker-compose restart code block - Remove trailing whitespace - Add blank line after Python code fence for proper list continuation - Guard against missing access token in server.py get_access_token_claims tool: - Check if token or token.claims is None before accessing claims - Raise RuntimeError with clear message instead of AttributeError - Provides better error handling for unauthenticated requests - Preserve Authorization header when proxying client registration in keycloak.py: - Forward all incoming headers except Host to support authenticated DCR - Enables realms that require initial access tokens or bearer tokens - Avoids routing issues by excluding Host header - Ensures Content-Type is always application/json for modified body These changes improve error handling, support authenticated Dynamic Client Registration scenarios, and ensure documentation passes linting checks.
1 parent eb73267 commit 6f5622c

File tree

3 files changed

+16
-4
lines changed

3 files changed

+16
-4
lines changed

examples/auth/keycloak_auth/keycloak/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ This script will:
2525

2626
The Docker setup automatically imports a preconfigured realm configured for dynamic client registration. The default settings are described below and can be adjusted or complemented as needed by editing the [`realm-fastmcp.json`](realm-fastmcp.json) file before starting Keycloak. If settings are changed after Keycloak has been started, restart Keycloak with
2727

28-
```
28+
```bash
2929
docker-compose restart
3030
```
3131

32-
to apply the changes.
32+
to apply the changes.
3333

3434
### Realm: `fastmcp`
3535

@@ -127,4 +127,5 @@ docker-compose logs -f keycloak
127127
# Or clear all OAuth cache data
128128
FileTokenStorage.clear_all()
129129
```
130+
130131
- After clearing the cache, run your client again to automatically re-register with Keycloak

examples/auth/keycloak_auth/server.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ def echo(message: str) -> str:
5151
async def get_access_token_claims() -> dict:
5252
"""Get the authenticated user's access token claims."""
5353
token = get_access_token()
54+
if token is None or token.claims is None:
55+
raise RuntimeError("No valid access token found. Authentication required.")
56+
5457
return {
5558
"sub": token.claims.get("sub"),
5659
"name": token.claims.get("name"),

src/fastmcp/server/auth/providers/keycloak.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,19 @@ async def register_client_proxy(request):
280280
logger.info(
281281
f"Forwarding client registration to Keycloak: {self.oidc_config.registration_endpoint}"
282282
)
283+
# Forward all headers except Host (to avoid routing issues)
284+
forward_headers = {
285+
key: value
286+
for key, value in request.headers.items()
287+
if key.lower() != "host"
288+
}
289+
# Ensure Content-Type is set correctly for our JSON body
290+
forward_headers["Content-Type"] = "application/json"
291+
283292
response = await client.post(
284293
self.oidc_config.registration_endpoint,
285294
content=body,
286-
# Set headers explicitly to avoid forwarding host/authorization that might conflict
287-
headers={"Content-Type": "application/json"},
295+
headers=forward_headers,
288296
)
289297

290298
if response.status_code != 201:

0 commit comments

Comments
 (0)