我有一个微服务,它以不同的授权支持两个用户 user 和 admin 的HttpBasic身份验证。现在,我有一个Web应用程序,要求登录并将操作委托给第一个微服务。
我正在以这种方式使用@LoadBalanced
和RestTemplateBuilder
@LoadBalanced
@Bean
RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.basicAuthorization("x", "x").build();
}
获得授权的/负载均衡的RestTemplate
来访问我的微服务,但是这种设计意味着无论 user <是什么,凭据始终为 x-x / em>和密码用于登录Web应用。
我知道我可以使用类似的东西
@Autowired
private RestTemplateBuilder restTemplateBuilder;
public String callSecureService() {
// ... get principal and password
RestTemplate restTemplate = restTemplateBuilder.basicAuthorization([user], [password]).build();
return restTemplate.getForObject("http://localhost:8080/secureAPI",String.class);
}
使用用于登录Web应用程序的凭据来调用微服务,但这意味着失去功能区的负载平衡功能。
所以,我的问题是,有没有办法兼顾两者(负载平衡和动态身份验证)?还是我理解错了,设计不应该是那样?
(示例代码取自javadeveloperzone.com 1)
答案 0 :(得分:0)
好的,感谢here,我找到了解决方案。通常,我们不再使用@LoadBalanced
,而是使用LoadBalancerClient
和RestTemplateBuilder
的组合来为每个请求提供授权。我将在下面保留相关代码。谢谢大家。
@Autowired
protected RestTemplateBuilder restTemplateBuilder;
@Autowired
private LoadBalancerClient loadBalancer;
protected String serviceAlias;
public EmpleadosWebService(String serviceAlias) {
this.serviceAlias = serviceAlias;
}
private RestTemplate getRestTemplateWithCurrentAuth() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
return restTemplateBuilder.basicAuthorization(auth.getName(), (String) auth.getCredentials()).build();
}
private String getBaseUrl() {
ServiceInstance serviceInstance = loadBalancer.choose(this.serviceAlias);
// We could log this string to check the load balancing
return serviceInstance.getUri().toString();
}
public Empleado getEmpleado(String cif) {
return getRestTemplateWithCurrentAuth().getForObject(this.getBaseUrl() + "/empleados/{cif}",
Empleado.class, cif);
}
...
另一件事:要从Spring 3.1开始访问凭据(密码),我们需要像这样配置AuthenticationManagerBuilder
auth.eraseCredentials(false)
或登录后,凭据将从内存中删除。