10

I am using Spring Boot to write an application that interacts with HTTP rest servers. One of the servers I'm connecting to (Wit.ai) uses a beaerer authorization token. A curl request that yields a successful response looks like this:

GET /message?q=sample message HTTP/1.1
Host: api.wit.ai
Authorization: Bearer XXXXXXXXXXXXX
Cache-Control: no-cache
Postman-Token: 526c3a11-8e61-4552-aa19-e913f6473753

The wit.ai docs say the following about the token,

Wit.ai uses OAuth2 as an authorization layer. As such, every API request must contain an Authorize HTTP header with a token Access tokens are app specific.

I am trying to send a GET request to this endpoint in a Spring Boot app using @FeignClient. However I the endpoint doesn't seem to be accepting my authorization token. Here is my FeignClient code

@FeignClient(name="witGetter", url = "${wit.url}")
    public interface WitGetter {
        @RequestMapping(method = RequestMethod.GET, value = "/message?v=20180507q={text}",
            headers = {"Authorization: Bearer XXXXXXXXXXXXX"})
        WitResponse getWitResponse(@PathVariable("text") final String text);
}

What is the proper way to pass such an authorization token? I have tried a few other things but to no avail. Thanks for any advice!!!

By the way, the following code works using a traditional Feign interface, but I need to use @FeignClient in this case.

public interface WitGetter {
    @Headers("Authorization: Bearer XXXXXXXXXXXXX")
    @RequestLine("GET /message?q={text}")
    WitResponse getWitResponse(@Param("text") String text);
}

(code below is in a separate config file)

@Bean
    public WitGetter defaultWitGetter(@Value("https://api.wit.ai") final String witUrl){
        return Feign.builder().decoder(new GsonDecoder()).target(WitGetter.class, witUrl);

}

EDIT

The error code I get when using the above code is:

Exception in thread "main" feign.FeignException: status 400 reading WitGetter#getWitResponse(String,String); content: { "error" : "Bad auth, check token/params", "code" : "no-auth" }

Trey Bernstien
  • 103
  • 1
  • 1
  • 7

1 Answers1

16

When using Feign via Spring Cloud, you can use it as you would define a standard Spring MVC controller.

Please check my article here about passing headers with Feign: https://arnoldgalovics.com/passing-headers-with-spring-cloud-feign/

Quick hint: you can add a @RequestHeader("Authorization") String bearerToken parameter to the method definition.

And then of course call it like client.method(..., "Bearer " + token)

velsim
  • 496
  • 8
  • 15
galovics
  • 2,884
  • 3
  • 15
  • 25
  • I want to have this `bearerToken` to be fetched from `application properties` file. I have them constant for a a Proxy Interface but variable across production & staging environments. What would be the best way to do that? The Feign Proxy Interface wouldn't let me use `@Value` and I do not want to hard code this token in my code – krozaine Jun 23 '20 at 13:36
  • Is there a way to make this posible using filters? Just to do it in one simple filter and not to every request from the feign client.. – Carlos Cruz Sep 28 '20 at 23:21
  • @CarlosCruz yes, refer this one: https://arnoldgalovics.com/customizing-each-request-with-spring-cloud-feign/ – galovics Sep 29 '20 at 20:44