Spring Cloud Feign 与 OAuth2RestTemplate
Spring Cloud Feign with OAuth2RestTemplate
我正在尝试实施 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();
}
Feign 不使用 RestTemplate
,因此您必须找到其他方法。如果您创建类型为 feign.RequestInterceptor
的 @Bean
,它将应用于所有请求,因此其中一个带有 OAuth2RestTemplate
的请求(仅用于管理令牌获取)可能是最好的选项。
这是我的解决方案,只是为了补充另一个答案与源代码,实现接口 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());
}
};
}
我正在尝试实施 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();
}
Feign 不使用 RestTemplate
,因此您必须找到其他方法。如果您创建类型为 feign.RequestInterceptor
的 @Bean
,它将应用于所有请求,因此其中一个带有 OAuth2RestTemplate
的请求(仅用于管理令牌获取)可能是最好的选项。
这是我的解决方案,只是为了补充另一个答案与源代码,实现接口 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());
}
};
}