elasticsearch-java
elasticsearch-java copied to clipboard
Per-Request Headers
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.
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?
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.
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.
Hello @mdgilene, is this still an issue for you or did @fpeter8's solution work?
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.