adityamparikh opened a new pull request, #190:
URL: https://github.com/apache/solr-mcp/pull/190
## Problem
`docs/security/keycloak.md`'s Quick Start cannot be completed as written.
Following it verbatim gives you a server that exits 1 printing nothing but the
Spring banner — and once past that, **every tool call is rejected**.
Three independent gaps, all reproduced against Keycloak 26.0:
### 1. Step 2 had no commands
```bash
# 2. Configure Keycloak (see detailed steps below)
# - Create realm: solr-mcp
# - Create client: solr-mcp-client
```
A comment, so it reads as skippable. It is not. `HttpSecurityConfiguration`
wires OAuth2 only when an issuer is set, and `McpServerOAuth2Configurer` builds
its `NimbusJwtDecoder` **eagerly during `init()`** — so an `OAUTH2_ISSUER_URI`
pointing at a realm that does not exist aborts context refresh:
```
Error creating bean with name 'securityFilterChain':
Unable to resolve the Configuration with the provided Issuer of
"http://localhost:8180/realms/solr-mcp"
```
Note the asymmetry that makes this sharp: an issuer left **empty** starts
fine (the chain still returns 401/403). Only a configured-but-unresolvable
issuer kills startup.
### 2. No audience mapper — so every tool call 401s
`HttpSecurityConfiguration` sets `validateAudienceClaim(true)` against the
resource indicator from `resourcePath("/mcp")`. Keycloak does not populate
`aud` on its own; a token from the documented client carries only:
```json
"aud": "account"
```
Result:
```
401 WWW-Authenticate: Bearer error="invalid_token",
error_description="... The aud claim is not valid"
```
`docs/security/http.md` already documents that Keycloak needs an Audience
protocol mapper — `keycloak.md` just never applied it. This PR adds it to both
the scripted and console paths and cross-links `http.md`.
### 3. Test users could not get a token at all
The documented user creation omits first/last name, which Keycloak's default
user profile requires:
```json
{"error":"invalid_grant","error_description":"Account is not fully set up"}
```
## What changed
- **Step 2 is now runnable `kcadm` commands** — realm, public client,
audience mapper, user, password.
- **New step 4 proves security is actually on.** An anonymous `tools/list`
*succeeds* by design (`/mcp` is permitted at the HTTP layer; authorization is
per-tool via `@PreAuthorize`), so only a `tools/call` distinguishes a secured
server from an unsecured one. Both outcomes are shown.
- Console instructions gain the audience mapper, the first/last name fields,
and a note that **Direct access grants** is what makes the existing
password-grant `curl` work.
- Troubleshooting gains the four failure modes actually encountered, each
with its real symptom text.
## Verification
The whole Quick Start was executed verbatim against Keycloak 26.0 **from a
freshly deleted and recreated realm**. Recorded outputs are the real ones:
```
--- unauthenticated:
{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"Access
Denied"}],"isError":true}}
--- authenticated:
{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"[\"books\",\"films\",\"streaming-shows\"]"}],"isError":false}}
```
Audience mapper effect confirmed by removing it and re-testing: `aud` drops
to `account` and the same call returns `401 "The aud claim is not valid"`.
Docs-only — no source or test changes.
## Related
Diagnosing this surfaced a separate bug that made the failure invisible:
`logback.xml` shadows `logback-spring.xml`, so HTTP mode logs nothing and the
startup exception above never reaches the console. Fixed in #189. The
troubleshooting section here mentions the
`LOGGING_CONFIG=classpath:logback-spring.xml` workaround so this doc stands
alone whether or not #189 has merged.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Bbs8w62uwcx12ZE8E2xg8P
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]