对于我的基于微服务架构的应用程序,我同时使用了 user 和 service accounts。我猜弹簧安全适配器只处理与用户相关的东西(至少我正在使用的版本是 2.2.1)。我要做的是拥有另一个RestTemplate,我自己处理它以便作为客户端访问资源。
举个例子:
@Service
public class RemoteAccessService{
//Manages user access
private KeycloakRestTemplate userAccessRestTemplate;
//Manages client access
private RestTemplate clientAccessRestTemplate;
public RemoteAccessService(KeycloakRestTemplate userAccessRestTemplate,
@Qualifier("clientAccessRestTemplate") RestTemplate clientAccessRestTemplate;){
}
}
然后,您在 @Configuration 类中构建一个 RestTemplate bean 以管理客户端授权:
@Bean
public RestTemplate clientAccessRestTemplate() {
RestTemplate template = new RestTemplate();
template.getMessageConverters().add(new FormHttpMessageConverter());
template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
template.getInterceptors().add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
//Intercept each of the requests performed by this template
//and add the client access token in the Authorization header
HttpRequest wrapper = new HttpRequestWrapper(request);
if (clientAccessToken != null) {
wrapper.getHeaders().set("Authorization",
"Bearer " + clientAccessToken.getToken());
}
return execution.execute(wrapper, body);
}
});
return template;
}
当然,你需要确保你在拦截器中有一个正确的clientAccessToken,否则你会得到一个 401 或 403 代码。在这里,您有一个 post 说明如何在 OAuth 中执行此操作(您不需要用户/密码,只需客户端凭据)。
作为旁注,keycloak 适配器可以方便地管理某些情况,但它们不提供对 keycloak 的所有功能的访问,这是一种更强大的方式。