elasticsearch-java icon indicating copy to clipboard operation
elasticsearch-java copied to clipboard

Per-Request Headers

Open mdgilene opened this issue 11 months ago • 5 comments

Description

Currently I do not see a way to provide per-request headers anywhere in the API. This would be needed for things like JWT authorization documented here https://www.elastic.co/guide/en/elasticsearch/reference/current/jwt-auth-realm.html#hmac-oidc-example-request-headers

The only current solution it seems would be to re-build the entire client with every request which seems extremely wasteful.

mdgilene avatar Jul 12 '23 15:07 mdgilene

You can add both a credential provider and a http request interceptor to the rest client:

RestClient.builder(HttpHost.create("url"))
	.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(elasticCredentialsProvider)
		.addInterceptorFirst((HttpRequestInterceptor) (request, context) -> {
			request.addHeader("Authorization", value);
		})
)
.build();

Did you mean something else?

fpeter8 avatar Aug 16 '23 14:08 fpeter8

My specific use case was the need to basically send a request "on behalf" of another user, not just using something like client_credential grant. So, a user makes a request to my service with their authorization token, I then pass that on to elastic so I can take advantage of all of the x-pack security features.

mdgilene avatar Aug 16 '23 15:08 mdgilene

I have implemented Proxy authentication inside the interceptor before, that should work for you as well. It runs before every call to the Elastic cluster, so you can set custom headers and/or parameters for each call individually.

fpeter8 avatar Aug 16 '23 16:08 fpeter8

Hello @mdgilene, is this still an issue for you or did @fpeter8's solution work?

l-trotta avatar Apr 18 '24 16:04 l-trotta

We ended up going a different direction, so this wasn't specifically needed in the end.

However, to the solution he provided; I think this would work for setting the JWT like I had mentioned. In our case I probably could have used Springs SecurityContextHolder to obtain and inject the token. However, I'm not sure the solution extends more generically as the context in which the interceptor would be created would be during Bean initialization. So, unless you had a static way to reference whatever value you wanted to inject you couldn't do something for example like pull a query parameter out of the request a user made and pass that along by way of a custom header.

I understand Elasticsearch doesn't make much use of headers with its API so the example I gave may seem a bit weird, however there are cases where setting headers are required if let's say there is a proxy in-between you and Elasticsearch.

mdgilene avatar Apr 20 '24 02:04 mdgilene