Implementation similar to Feign's RequestInterceptor with MicroProfile RestClient

307 views
Skip to first unread message

Everton da Silva Barros

unread,
Jan 23, 2020, 3:34:02 PM1/23/20
to Quarkus Development mailing list
I have to communicate with another service that requires authentication. So in SpringBoot I do this:

Component
public class RequestReponseService implements RequestInterceptor {
private static final String HTTP_BIN_URL = "http://localhost:8080";
public static final String USERNAME = "user;
public static final String PASSWORD = "passwd";
@Override
public void apply(RequestTemplate template) {
BasicAuthRequestInterceptor interceptor = new BasicAuthRequestInterceptor(USERNAME, PASSWORD);
HttpBinService bookResource = Feign.builder().encoder(new JacksonEncoder())
        .decoder(new JacksonDecoder()).requestInterceptor(interceptor)
        .target(HttpBinService.class, HTTP_BIN_URL);
template.header("Authorization", "Bearer " + bookResource.getAuthenticatedUser().getAccess_token());
}
}


@Headers("Content-Type: application/x-www-form-urlencoded")
public interface HttpBinService {

@RequestLine("POST /token?grant_type=client_credentials")
AuthStatus getAuthenticatedUser();
}


With that I don't need to call my authentication service every time I need to call my business service. My question is, how can I do the same using quarkus with MicroProfile RestClient? Is it possible to create a RequestInterceptor or something similar?


@Path("/v1")
@RegisterRestClient
@ClientHeaderParam(name = "X-AccessKey", value = "{lookupAuth}")
public interface MyService {

    @GET
    @Produces("application/json")
    Object getData();
    
    default String lookupAuth() {
return "Basic " + Base64.getEncoder().encodeToString("user:passwd!".getBytes()); //I'm stuck here! How to return the token and pass it to the header of the business service?
}
}






Ken Finnigan

unread,
Jan 23, 2020, 3:41:43 PM1/23/20
to Quarkus Development mailing list
Do you mean how to pass the token onto the MyService.getData() call?

@ClientHeaderParam is already setting a Header value on that outgoing request.

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/2a0dc09f-89e2-48ea-8b8b-d7bccfa1a6bc%40googlegroups.com.

Everton da Silva Barros

unread,
Jan 23, 2020, 3:51:18 PM1/23/20
to Quarkus Development mailing list
Exact. I want to pass the token that I get from the answer, similarly as it is done with Feign in the example above. Note that in Feign, this is clear through the Interceptor, which I obtain with a single interception.
To unsubscribe from this group and stop receiving emails from it, send an email to quark...@googlegroups.com.

Ken Finnigan

unread,
Jan 23, 2020, 3:55:26 PM1/23/20
to everton...@gmail.com, Quarkus Development mailing list
The @ClientHeaderParam causes the result of lookupAuth() to be added to the Header param named "X-AccessKey" onto the outgoing request.

I might be missing something, but what more is needed?

To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/5eb163ae-da77-47e0-bbce-01bc9e7c37f9%40googlegroups.com.

Stuart Douglas

unread,
Jan 23, 2020, 4:06:05 PM1/23/20
to everton...@gmail.com, Quarkus Development mailing list
Are you having trouble getting the credential you need? If so you should be able to access it by injecting the SecurityIdentity and looking at the credentials.

Stuart

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.

Sergey Beryozkin

unread,
Jan 24, 2020, 4:43:14 AM1/24/20
to Stuart Douglas, everton...@gmail.com, Quarkus Development mailing list
We have an OIDC issue to get the OIDC client acquiring a token, once that issue is resolved we can also consider how that client invocation can be tied to the regular MP RestClient call, may be via JAX-RS ClientRequestFilter or indeed - annotation...

Thanks, Sergey 

William Burke

unread,
Jan 25, 2020, 8:37:29 AM1/25/20
to Siarhei Biarozkin, Stuart Douglas, everton...@gmail.com, Quarkus Development mailing list
Just write a ClientRequestFilter?  There must be some upfront config you have to do anyways, i.e. provide the auth endpoint and credentials.  Doing this declaratively doesn't seem right



--
Bill Burke
Red Hat

Sergey Beryozkin

unread,
Jan 27, 2020, 8:51:03 AM1/27/20
to William Burke, Stuart Douglas, everton...@gmail.com, Quarkus Development mailing list
Hi Bill

That is the plan, if I understand your comment correctly. We've had a user asking for an enhancement before, and sharing the filter they wrote. Once we have an OOB support for such an out of band OIDC client acquiring a token, we can review how to make it easily available. Invoking it from ClientRequestFilter would be easy. Perhaps it would be injectable in the service code as well, in case when a non-JAX-RS/MP JWT request is used, etc...Not sure about the viability of connecting this client to the current MP JWT client via an annotation yet, but we can review all the options when we have this OIDC client :-)

Thanks, Sergey

Sergey Beryozkin

unread,
Jan 27, 2020, 10:24:52 AM1/27/20
to William Burke, Stuart Douglas, everton...@gmail.com, Quarkus Development mailing list
Sorry I meant MP Rest Client :-)

William Burke

unread,
Jan 27, 2020, 11:36:15 AM1/27/20
to Sergey Beryozkin, Stuart Douglas, everton...@gmail.com, Quarkus Development mailing list
What i'm hinting at is that I don't think security should be triggered by an annotation, i.e.  Should be triggered by config or manual ClientConfiguration registration.

@OIDC
@Path
public MyResource {
}

Everton da Silva Barros

unread,
Jan 27, 2020, 2:00:21 PM1/27/20
to Quarkus Development mailing list
I don't know if this is the best practice. But for now I solved it that way:

public class AuthStatus {
   
public RestAccess rest_access;
public static class RestAccess {
public long access_key;
}
}


@ClientHeaderParam(name = "Content-Type", value = "application/json")
@ClientHeaderParam(name = "Accept", value = "application/json")
@ClientHeaderParam(name = "Authorization", value = "{lookupAuth}")
public interface HttpBinService {
@POST
@Path("/rest_access")
AuthStatus getAuthenticatedUser(String body);
default String lookupAuth() {
return "Basic " + Base64.getEncoder().encodeToString("user:passwd".getBytes());
}
}


public class CheckRequestFilter implements ClientRequestFilter {

private static final Logger LOG = Logger.getLogger(CheckRequestFilter.class);
private static final String HTTP_BIN_URL = "http://{myID}:8050/caisd-rest/";

@Override
public void filter(ClientRequestContext requestContext) throws IOException {
try { 
HttpBinService service = RestClientBuilder.newBuilder().baseUri(new URI(HTTP_BIN_URL)).build(HttpBinService.class);
StringBuilder json = new StringBuilder();
json.append("{");
json.append("\"rest_access\":\"\"");
json.append("}");
AuthStatus auth = service.getAuthenticatedUser(json.toString());
requestContext.getHeaders().add("X-AccessKey", auth.rest_access.access_key);
} catch (Exception e) {
LOG.error(e);
}
}
}



@Path("/caisd-rest")
@RegisterRestClient
@RegisterProvider(value = CheckRequestFilter.class)
@ClientHeaderParam(name = "Content-Type", value = "application/json")
@ClientHeaderParam(name = "Accept", value = "application/json")
public interface RdmService {

@POST
@Path("/chg")
MyObjetct create(String jsonBody);
To unsubscribe from this group and stop receiving emails from it, send an email to quark...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quark...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quark...@googlegroups.com.


--
Bill Burke
Red Hat
Reply all
Reply to author
Forward
0 new messages