使用OAuth2RestTemplate进行Spring Cloud Feign

时间:2015-04-03 21:04:25

标签: spring-security-oauth2 spring-cloud

我尝试使用Feign客户端从用户的服务中获取用户信息,目前我正在使用oAuth2RestTemplate进行请求,它可以正常工作。但是现在我希望改为Feign,但是我收到错误代码401可能是因为它没有携带用户令牌,因此有一种方法可以自定义,如果Spring支持Feign,则使用RestTemplate所以我可以使用自己的Bean?

今天我以这种方式实施

客户服务

@Retryable({RestClientException.class, TimeoutException.class, InterruptedException.class})
@HystrixCommand(fallbackMethod = "getFallback")
public Promise<ResponseEntity<UserProtos.User>> get() {
    logger.debug("Requiring discovery of user");
    Promise<ResponseEntity<UserProtos.User>> promise = Broadcaster.<ResponseEntity<UserProtos.User>>create(reactorEnv, DISPATCHER)
            .observe(Promises::success)
            .observeError(Exception.class, (o, e) -> Promises.error(reactorEnv, ERROR_DISPATCHER, e))
            .filter(entity -> entity.getStatusCode().is2xxSuccessful())
            .next();
    promise.onNext(this.client.getUserInfo());
    return promise;

}

和客户

@FeignClient("account")
public interface UserInfoClient {

    @RequestMapping(value = "/uaa/user",consumes = MediaTypes.PROTOBUF,method = RequestMethod.GET)
    ResponseEntity<UserProtos.User> getUserInfo();
}

2 个答案:

答案 0 :(得分:8)

Feign没有使用RestTemplate,因此您必须找到不同的方式。如果您创建@Bean类型feign.RequestInterceptor,它将应用于所有请求,因此可能其中一个OAuth2RestTemplate(仅用于管理令牌获取)将是最好的选项。

答案 1 :(得分:5)

这是我的解决方案,只是为了补充源代码的另一个答案,实现接口feign.RequestInterceptor

@Bean
public RequestInterceptor requestTokenBearerInterceptor() {
    return new RequestInterceptor() {
        @Override
        public void apply(RequestTemplate requestTemplate) {
            OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)
                    SecurityContextHolder.getContext().getAuthentication().getDetails();

            requestTemplate.header("Authorization", "bearer " + details.getTokenValue());
        }
    };
}