WMK666666 opened a new pull request, #29593:
URL: https://github.com/apache/camel/pull/29593

   `authenticationScheme=BEARER` and `oauthProfile` never sent any credentials 
at all.
   
   The only authentication the docling-serve client knows is an API key, which 
it always puts in the `X-Api-Key` header, and `DoclingProducer` only called 
`builder.apiKey(...)` in the `API_KEY` branch:
   
   ```java
   // Apply API key authentication if configured
   if (configuration.getAuthenticationScheme() == AuthenticationScheme.API_KEY
           && configuration.getAuthenticationToken() != null) {
       builder.apiKey(configuration.getAuthenticationToken());
   }
   
   doclingServeApi = builder.build();
   ```
   
   So a `BEARER` endpoint -- including **every** endpoint using `oauthProfile`, 
because `resolveOAuthToken()` sets the scheme to `BEARER` right after it 
resolves the token -- started up fine, logged `with authentication: BEARER`, 
and then sent every request without an `Authorization` header. docling-serve 
itself has no built-in auth; it is secured by putting an OAuth proxy in front 
of it ([docling-serve 
docs](https://github.com/docling-project/docling-serve/blob/main/docs/deployment.md)),
 and that proxy wants `Authorization: Bearer <token>`. So the documented 
Bearer/OAuth setup produced 401 on every request while the endpoint looked 
correctly configured, with nothing in the log to explain it.
   
   ### Fix
   
   The client has no builder option for any other header 
(`DoclingServeApiConfig` only carries `API_KEY`, in 0.7.1 as well), but it does 
leave `createRequestBuilder(RequestContext)` open for subclasses. 
`BearerTokenDoclingServeClient` extends `DoclingServeClient` and adds the 
header there; `DoclingProducer` uses it when the scheme is `BEARER`. Everything 
else -- the HTTP setup, the operations, and the JSON codec -- is the same as 
the client the builder would have created, so the only difference between an 
`API_KEY` and a `BEARER` endpoint is which header carries the credentials.
   
   `getDoclingServeApi()` is package private so the producer's wiring can be 
asserted directly, without a real docling-serve.
   
   ### Test
   
   `DoclingProducerAuthTest` starts a stub docling-serve on a loopback port and 
asserts what actually goes on the wire for each scheme:
   
   | scheme | `Authorization` | `X-Api-Key` |
   | --- | --- | --- |
   | `BEARER` | `Bearer secret-token` | absent |
   | `API_KEY` | absent | `secret-token` |
   | `NONE` | absent | absent |
   
   Reverting only the `BEARER` branch in `DoclingProducer` makes exactly the 
first row fail (`expected: "Bearer secret-token" but was: null`) and leaves the 
other two green.
   
   ```
   mvn -pl components/camel-ai/camel-docling test
   Tests run: 89, Failures: 2, Errors: 0, Skipped: 15
   ```
   
   The two failures are 
`DoclingCustomArgsValidationTest.customArgsWithAbsolutePath{,EqualsForm}AreRejected`,
 and they are unrelated and pre-existing **on Windows**: `/etc/cron.d` is not 
an absolute path there, so the absolute-path guard does not fire and the 
request fails later with an `IOException`. They fail identically with this 
change reverted to the original `DoclingProducer`. Everything else, plus 
`install` with formatter, license, enforcer and rat, passes.
   
   ### Note on the upstream fix
   
   Adding a `bearerToken(...)` option to `ai.docling:docling-serve-client` 
would be the natural place for this, and this subclass could then go away. I am 
happy to open that upstream and rework this PR on top of a release if you would 
rather not carry the subclass in the meantime.
   


-- 
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]

Reply via email to