Spring boot Oauth2:使用 Feign、Ribbon、Zull 和 Eureka 从客户端到资源的令牌中继
Spring boot Oauth2 : Token relay from a client using Feign, Ribbon, Zull and Eureka to a ressource
我有一个 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 也可以中继令牌,但不是很方便我更喜欢以前的方法。
@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);
}
}
如果我正确理解了你的问题,那么你可以使用 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;
}
这就是我所做的让它发挥作用。
@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;
}
我有一个 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 也可以中继令牌,但不是很方便我更喜欢以前的方法。
@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);
}
}
如果我正确理解了你的问题,那么你可以使用 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;
}
这就是我所做的让它发挥作用。
@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;
}