Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting basic auth in microprofile rest client

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?

like image 686
Martin Nielsen Avatar asked Feb 05 '26 11:02

Martin Nielsen


2 Answers

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:

  • Create an interface that extends the one you use with this annotation:
@ClientHeaderParam(name = "Authorization", value = "{lookupAuth}")
public interface MyServiceWrapper extends MyService {
  default String lookupAuth() {
    return "Basic " + Base64.getEncoder().encodeToString("someuser:somepass".getBytes());
  }
}
  • Create a 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);
like image 63
geoand Avatar answered Feb 07 '26 18:02

geoand


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.

like image 22
Luca Basso Ricci Avatar answered Feb 07 '26 16:02

Luca Basso Ricci