I have a service which exposes a number of Jax-RS interfaces for its services. I now want to use those interfaces to connect with the services. I am using Quarkus, which means I am using the microprofile rest client. Because I already have the JaxRS interface, using the @RegisterRestClient method is not really viable. Instead I am using the RestClientBuilder.
MyService client = RestClientBuilder.newBuilder()
.baseUri(URI.create("https://localhost:8080"))
.build(MyService.class);
The problem I am running into is authentication. The services i need to reach are locked behind basic Auth. All the guides I have found for the microprofile REST client are variations of this where the solution is to add a headerparam. This is not possible however, because I already have the interface premade, and copy-pasting the entire thing to add a header parameter is really something i would rather avoid.
It should also be mentioned that i have tried a @Provider filter to set the headers, but I can't seem to figure out how to only target a single REST client using that method, and I have several.
So: How do i set up basic authentication without messing with the Jax-Rs interface itself, using the microprofile rest client?
UPDATE
Starting from Quarkus 3.9, you will be able to do:
@Path("/my")
@ClientBasicAuth(username = "${service.username}", password = "${service.password}")
public interface MyService {
}
where service.username and service.password are configuration properties that must be set at runtime to the username and password that allow access to the service being called.
ORIGINAL ANSWER
You should be able to use the @ClientHeaderParam annotation on MyService.
Something like:
@Path("/my")
@ClientHeaderParam(name = "Authorization", value = "{lookupAuth}")
public interface MyService {
default String lookupAuth() {
return "Basic " +
Base64.getEncoder().encodeToString("someuser:somepass".getBytes());
}
}
See this for more details
If modifying the interface is not possible, you have two options:
@ClientHeaderParam(name = "Authorization", value = "{lookupAuth}")
public interface MyServiceWrapper extends MyService {
default String lookupAuth() {
return "Basic " + Base64.getEncoder().encodeToString("someuser:somepass".getBytes());
}
}
ClientRequestFilter that fills the Authorization header:@Priority(Priorities.AUTHENTICATION)
public class BasicRequestFilter implements ClientRequestFilter {
@Override
public void filter(ClientRequestContext requestContext) throws IOException {
requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, getAccessToken());
}
private String getAccessToken() {
return "Basic " + Base64.getEncoder().encodeToString("someuser:somepass".getBytes());
}
}
And register the filter, e.g. programmatically:
MyService client = RestClientBuilder.newBuilder()
.register(BasicRequestFilter.class)
.baseUri(URI.create("https://localhost:8080"))
.build(MyService.class);
You can register a per-instance org.jboss.resteasy.client.jaxrs.internal.BasicAuthentication (or you can write a similar component) and register it using RestClientBuilder.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With