To collect the token with Feign you need the following:
import java.util.Map;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
@FeignClient(name = "oauth2", url = "https://dev-XXXXXX.okta.com/oauth2/default/v1")
public interface TokenFetcher {
@PostMapping(value = "/token", consumes = APPLICATION_FORM_URLENCODED_VALUE)
String token(@RequestBody Map<String, ?> form);
class Configuration {
@Bean
Encoder feignFormEncoder(ObjectFactory<HttpMessageConverters> converters) {
return new SpringFormEncoder(new SpringEncoder(converters));
}
}
}
Use the client like this:
@Autowired
TokenFetcher tokenFetcher;
public void test() {
Map<String, Object> form = new HashMap<>();
form.put("client_id", "xxxxxx");
form.put("client_secret", "xxxxxx");
form.put("grant_type", "client_credentials");
String jwt = tokenFetcher.token(form);
}
Dependencies are:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
In order to use the token you must to add it token as the 'authorization' header with a prefix of 'Bearer ' (note the space) on each call. The easiest way to do this is be adding a RequestInterceptor to your FeignClient as follows:
public class FeignConfiguration {
@Bean
public RequestInterceptor requestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
String jwtTokenStoredSomewhere = null;
if (requestTemplate.request().url().startsWith("https://site1")) {
jwtTokenStoredSomewhere = site1JwtTokenStoredSomewhere;
} else if (requestTemplate.request().url().startsWith("https://site2")) {
jwtTokenStoredSomewhere = site2JwtTokenStoredSomewhere;
} else {
jwtTokenStoredSomewhere = site3JwtTokenStoredSomewhere;
}
requestTemplate.header("Authorization", "Bearer " + jwtTokenStoredSomewhere);
}
}
}