如何将 Eureka 名称与 OAuth2RestTemplate 一起使用
How to use Eureka Names with OAuth2RestTemplate
我正在使用 OAuth2RestTemplate 以通过 REST 请求传递 oauth 令牌。但是,我现在需要硬编码我的网址,例如
restTemplate.postForLocation("http://localhost:5555/other-service2/message", "Message")
而当我使用自己创建的 Ribbon Annotated(使用 @LoadBalanced)RestTemplate bean 时,我可以做类似
的事情
restTemplate.postForLocation("http://service1/other-service2/message", "Message")
这是因为当您使用 LoadBalanced 时,它会自动使它成为一个 Ribbon Rest 模板,让您可以使用服务发现功能或 Eureka,但是当您使用 @Loadbalanced 注释 OAuth2RestTemplate bean 时,它会抛出某种尝试使用 OAuth2RestTemplate 时出现运行时错误,其中显示
o.s.b.a.s.o.r.UserInfoTokenServices : Could not fetch user details: class java.lang.IllegalStateException, No instances available for localhost
我的 OAuth2RestTemplate 创建看起来像
@LoadBalanced
@Bean
public OAuth2RestTemplate restTemplate(final UserInfoRestTemplateFactory factory) {
final OAuth2RestTemplate userInfoRestTemplate = factory.getUserInfoRestTemplate();
return userInfoRestTemplate;
}
如何在 OAuth2RestTemplate 上使用 Eureka 功能区的服务发现功能和负载平衡功能?
我想你可以试试这个。
在我的项目中,我们也使用OAuth2、Eureka、Ribbon 进行微服务之间的通信。为了将 Ribbon 与 OAuth2 一起使用,我们采用的方法有点不同。
首先我们保持 restTemplate 不变。
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
但是,我们创建了实现 RequestIntercepter 的 FeignClientIntercepter,它在通过 restTemplate 发出请求时为 OAuth 设置授权令牌。
@Component
public class UserFeignClientInterceptor implements RequestInterceptor {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String BEARER_TOKEN_TYPE = "Jwt";
@Override
public void apply(RequestTemplate template) {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
if (authentication != null && authentication
.getDetails() instanceof OAuth2AuthenticationDetails) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication
.getDetails();
template.header(AUTHORIZATION_HEADER,
String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue()));
}
}
}
并且如果您尝试创建 spring msa 项目,我更愿意使用 Feign-client 而不是 restTemplate。
@FeignClient("your-project-name")
public interface YourProjectClient {
@GetMapping("your-endpoint")
JsonObject getSomething();
我正在使用 OAuth2RestTemplate 以通过 REST 请求传递 oauth 令牌。但是,我现在需要硬编码我的网址,例如
restTemplate.postForLocation("http://localhost:5555/other-service2/message", "Message")
而当我使用自己创建的 Ribbon Annotated(使用 @LoadBalanced)RestTemplate bean 时,我可以做类似
的事情 restTemplate.postForLocation("http://service1/other-service2/message", "Message")
这是因为当您使用 LoadBalanced 时,它会自动使它成为一个 Ribbon Rest 模板,让您可以使用服务发现功能或 Eureka,但是当您使用 @Loadbalanced 注释 OAuth2RestTemplate bean 时,它会抛出某种尝试使用 OAuth2RestTemplate 时出现运行时错误,其中显示
o.s.b.a.s.o.r.UserInfoTokenServices : Could not fetch user details: class java.lang.IllegalStateException, No instances available for localhost
我的 OAuth2RestTemplate 创建看起来像
@LoadBalanced
@Bean
public OAuth2RestTemplate restTemplate(final UserInfoRestTemplateFactory factory) {
final OAuth2RestTemplate userInfoRestTemplate = factory.getUserInfoRestTemplate();
return userInfoRestTemplate;
}
如何在 OAuth2RestTemplate 上使用 Eureka 功能区的服务发现功能和负载平衡功能?
我想你可以试试这个。
在我的项目中,我们也使用OAuth2、Eureka、Ribbon 进行微服务之间的通信。为了将 Ribbon 与 OAuth2 一起使用,我们采用的方法有点不同。
首先我们保持 restTemplate 不变。
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
但是,我们创建了实现 RequestIntercepter 的 FeignClientIntercepter,它在通过 restTemplate 发出请求时为 OAuth 设置授权令牌。
@Component
public class UserFeignClientInterceptor implements RequestInterceptor {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String BEARER_TOKEN_TYPE = "Jwt";
@Override
public void apply(RequestTemplate template) {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
if (authentication != null && authentication
.getDetails() instanceof OAuth2AuthenticationDetails) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication
.getDetails();
template.header(AUTHORIZATION_HEADER,
String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue()));
}
}
}
并且如果您尝试创建 spring msa 项目,我更愿意使用 Feign-client 而不是 restTemplate。
@FeignClient("your-project-name")
public interface YourProjectClient {
@GetMapping("your-endpoint")
JsonObject getSomething();