我正在开发一个使用SpringBoot RestTemplateBuilder消耗第三方Rest api的客户端。 API需要身份验证。所以我使用基本身份验证来传递凭据。但它返回401 Unauthorized响应代码。
这是我在SpringBoot上的第一个项目。我尝试了差异方法,但结果相同。任何帮助我朝正确方向前进的帮助都将有所帮助。谢谢!
这是我的代码:
@SpringBootApplication
public class AysRestClientApplication {
private static final Logger log = LoggerFactory.getLogger(AysRestClientApplication.class);
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(AysRestClientApplication.class, args);
RestClient cl = ctx.getBean(RestClient.class);
cl.makeCall();
}
}
///////////
@Service
public class GetChangesMClient {
private final RestTemplate restTemplate;
private final String url = "https://sample.org/restapi";
public GetChangesMClient(RestTemplateBuilder restTemplateBuilder) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
interceptors.add(new HeaderRequestInterceptor("Accept", MediaType.APPLICATION_JSON_VALUE));
this.restTemplate = restTemplateBuilder.basicAuthorization("username", "password").build();
this.restTemplate.setInterceptors(interceptors);
}
public GetChangesMResponseTO execute(GetChangesMRequestTO request) {
return this.restTemplate.postForObject(url, request, GetChangesMResponseTO.class);
}
}
class HeaderRequestInterceptor implements ClientHttpRequestInterceptor {
private final String headerName;
private final String headerValue;
public HeaderRequestInterceptor(String headerName, String headerValue) {
this.headerName = headerName;
this.headerValue = headerValue;
System.out.println("Setting Interceptors");
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
System.out.println("intercepted");
request.getHeaders().set(headerName, headerValue);
return execution.execute(request, body);
}
}
///////////
@Service
public class RestClient {
@Autowired
private GetChangesMClient client;
public void makeCall(){
RequestTO request = new RequestTO();
ResponseTO response = this.client.execute(request);
}
}
这是我得到的错误:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:527)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.web.client.HttpClientErrorException: 401 Unauthorized
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:78)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
更新 我更改了我的代码以使用拦截器来设置BasicAuth,它现在正在运行。所以我不确定为什么SpringBoot basicAuthenticator方法不起作用。
拦截代码:
class BasicAuthInterceptor implements ClientHttpRequestInterceptor {
private String username;
private String password;
public BasicAuthInterceptor(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
HttpHeaders headers = httpRequest.getHeaders();
headers.add(HttpHeaders.AUTHORIZATION, encodeCredentialsForBasicAuth(username, password));
return clientHttpRequestExecution.execute(httpRequest, bytes);
}
public static String encodeCredentialsForBasicAuth(String username, String password) {
return "Basic " + Base64Utils.encodeToString((username + ":" + password).getBytes());
}
}
然后我就像使用它一样:
interceptors.add(new BasicAuthInterceptor("username", "pwd"));
我仍然想知道为什么我的第一种方法不起作用。