简体   繁体   中英

Implement Feign Client with Okta as Authorization Server

I was finally able to protect a rest api with Okta as OAuth2.0 security provider (basic with defaults). Also able to get the bearer token using curl, to call rest api via postman and get back results.

curl --location --request POST 'https://dev-XXXXXX.okta.com/oauth2/default/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=XXXXXXXXXXXXX' \
--data-urlencode 'client_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXX' \
--data-urlencode 'grant_type=client_credentials

Now i am trying to implement FeignClient (Rest client) in Spring Boot 2.X app to call the protected api, but facing difficulty in finding right documentation/samples as guide. Appreciate any directions/suggestions?

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) {
            requestTemplate.header("Authorization", "Bearer " + jwtTokenStoredSomewhere);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM