Spring boot Oauth2:使用 Feign、Ribbon、Zull 和 Eureka 从客户端到资源的令牌中继
Posted
技术标签:
【中文标题】Spring boot Oauth2:使用 Feign、Ribbon、Zull 和 Eureka 从客户端到资源的令牌中继【英文标题】:Spring boot Oauth2 : Token relay from a client using Feign, Ribbon, Zull and Eureka to a ressource 【发布时间】:2019-04-24 04:16:43 【问题描述】:我有一个成功从授权服务器获取令牌的 oauth2 客户端。 (并非总是如此,但现在是...... :))
客户端、zuul网关和资源服务器都注册在Eureka中。
我的客户端使用代理访问名为 microservice-files 的远程资源服务。
@RestController
@FeignClient(name = "zuul-server")
@RibbonClient(name = "microservice-files")
public interface ProxyMicroserviceFiles
@GetMapping(value = "microservice-files/root")
FileBean getUserRoot();
所以我想将令牌转发给 Zull,然后转发给资源服务器。
我可以通过这种方式传递令牌以联系 Zuul,显然负载平衡也得到了管理(我刚刚测试了我不知道,这很棒)zuul 也可以传递令牌,但这不是很方便我d更喜欢以前的方法。
@EnableConfigurationProperties
@SpringBootApplication
@EnableFeignClients("com.clientui")
public class ClientUiApplication
@Bean
public OAuth2RestOperations restOperations(
OAuth2ProtectedResourceDetails resource,
OAuth2ClientContext context)
return new OAuth2RestTemplate(resource, context);
public static void main(String[] args)
SpringApplication.run(ClientUiApplication.class, args);
这里是测试控制器
@Controller
public class ClientController
@Autowired
private RestOperations restOperations;
@RequestMapping("/root")
public ResponseEntity userRootTest()
String rootUrl = "http://localhost:9004/microservice-files/root";
return restOperations.getForEntity(rootUrl,FileBean.class);
【问题讨论】:
在这里找到解决方案***.com/questions/29439653/… 答案有点旧(3 年前),但它仍然可以完美运行。我不知道是否存在更新的更好的解决方案。 【参考方案1】:如果我正确理解了您的问题,那么您可以使用 RequestInterceptor 在假装的每个请求中添加一个令牌。为了做到这一点,你可以使用下一个配置:
@Bean
public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails resource)
return new OAuth2FeignRequestInterceptor(oauth2ClientContext, resource);
@Bean
protected OAuth2ProtectedResourceDetails resource()
AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
resource.setAccessTokenUri("http://127.0.0.1:9000/auth/login");
resource.setUserAuthorizationUri("http://127.0.0.1:9000/auth/authorize");
resource.setClientId("my-client");
resource.setClientSecret("my-secret");
return resource;
【讨论】:
感谢您的回答,它完美运行。我不知道哪一个是最好的解决方案。另一个只是在标头中添加令牌,它被中继,最后资源服务器可以检查它。在这里,我猜我们在客户端的每个 feign 请求中都会联系授权服务器。 OAuth2FeignRequestInterceptor 不会尝试在每个 feign 请求上获取新的令牌,这是实现仅当它在 OAuth2ClientContext 中丢失时才获取令牌,然后将此令牌放入上下文中并仅在令牌过期时刷新令牌。在这种情况下,您无需担心性能。 好的,如果其他解决方案没有在必要时刷新令牌;这是最好的解决方案 :) 感谢您的贡献 有没有办法,我们可以使用 Eureka 发现的名称而不是硬编码: resource.setAccessTokenUri("127.0.0.1:9000/auth/login"); //硬编码 resource.setAccessTokenUri("oauth-server/auth/login"); // 发现尤里卡。 .如果我尝试 Eureka Discovered name(oauth-server),我会收到错误:UnknownHostException @Hamid 我认为这是另一个问题,不幸的是解决起来并不简单。我希望这会有所帮助:github.com/spring-cloud/spring-cloud-security/issues/61【参考方案2】:这就是我所做的。
@Bean(name = "oauth2RestTemplate")
@LoadBalanced
public OAuth2RestTemplate restTemplate(SpringClientFactory clientFactory)
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails());
RibbonLoadBalancerClient ribbonLoadBalancerClient = new RibbonLoadBalancerClient(clientFactory);
LoadBalancerInterceptor loadBalancerInterceptor = new LoadBalancerInterceptor(ribbonLoadBalancerClient);
ClientCredentialsAccessTokenProvider accessTokenProvider = new ClientCredentialsAccessTokenProvider();
accessTokenProvider.setInterceptors(Arrays.asList(loadBalancerInterceptor));
restTemplate.setAccessTokenProvider(accessTokenProvider);
return restTemplate;
public ClientCredentialsResourceDetails resourceDetails()
ClientCredentialsResourceDetails clientCredentialsResourceDetails = new ClientCredentialsResourceDetails();
clientCredentialsResourceDetails.setId("1");
clientCredentialsResourceDetails.setClientId("my-ms");
clientCredentialsResourceDetails.setClientSecret("123");
clientCredentialsResourceDetails.setAccessTokenUri("http://oauth-server/oauth/token");
clientCredentialsResourceDetails.setScope(Arrays.asList("read"));
clientCredentialsResourceDetails.setGrantType("client_credentials");
return clientCredentialsResourceDetails;
【讨论】:
以上是关于Spring boot Oauth2:使用 Feign、Ribbon、Zull 和 Eureka 从客户端到资源的令牌中继的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 和 OAuth2 社交登录,无法获取 refreshToken
如何使用spring-boot 1.3.0.RC1为oauth2提供自定义安全性配置
让 oauth2 与 spring-boot 和 rest 一起工作
在反向代理后面使用 OAuth2 的 Spring Boot