Reputation: 851
I'm trying to to access a RestAPI-Endpoint with the help of Spring's RestTemplate
public List<Transaction> getTransactions() {
// only a 24h token for the sandbox, so not security critical
// still I replaced the last 10 digits here with 'x' but not in my original code
String authToken = "tylhtvGM6Duy8q0ZBbGaTg2FZefLfyeEeMZvCXlU2bEiinnZcLSACTxxxxxxxxxx";
String encodedAuthToken = Base64.getEncoder().encodeToString(authToken.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer "+encodedAuthToken );
ResponseEntity<TransactionsResponse> response = restTemplate.exchange(
"https://api-sandbox.starlingbank.com/api/v1/transactions",
HttpMethod.GET,
new HttpEntity<>("parameters", headers),
TransactionsResponse.class
);
return response.getBody().getEmbedded().getTransactions();
}
but I get a HttpClientErrorException saying "403 Forbidden". Long version
Caused by: org.springframework.web.client.HttpClientErrorException: 403 Forbidden
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:79) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:766) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
My code is based on a former stackoverflow thread and a call with the same parameters via Postman is successful:
So what is the problem?
Update
not encoding the authToken makes no difference
headers.add("Authorization", "Bearer tylhtvGM6Duy8q0ZBbGaTg2FZefLfyeEeMZvCXlU2bEiinnZcLSACTxxxxxxxxxx");
still leads to the same HttpClientErrorException: 403 Forbidden
Update2
I answered my question! (short version: UserAgent required. final code in anwser)
Upvotes: 8
Views: 41013
Reputation: 9377
For Bearer authentication Spring has a convenience method setBearerAuth(String token)
, since version 5.1:
// anonymised: replaced the last 10 digits here with 'x'
String authToken = "tylhtvGM6Duy8q0ZBbGaTg2FZefLfyeEeMZvCXlU2bEiinnZcLSACTxxxxxxxxxx";
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(authToken);
Upvotes: 2
Reputation: 851
this particular server requires an UserAgent! The value can be whatever, but it has to be present!
So the final version is:
public List<Transaction> getTransactions() {
// only a 24h token for the sandbox, so not security critical
// still I replaced the last 10 digits here with 'x' but not in my original code
String authToken = "tylhtvGM6Duy8q0ZBbGaTg2FZefLfyeEeMZvCXlU2bEiinnZcLSACTxxxxxxxxxx";
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("User-Agent", "Spring's RestTemplate" ); // value can be whatever
headers.add("Authorization", "Bearer "+authToken );
ResponseEntity<TransactionsResponse> response = restTemplate.exchange(
"https://api-sandbox.starlingbank.com/api/v1/transactions",
HttpMethod.GET,
new HttpEntity<>("parameters", headers),
TransactionsResponse.class
);
return response.getBody().getEmbedded().getTransactions();
}
Upvotes: 18
Reputation: 3181
If you are using OAuth Bearer tokens for authentication you don't need to encode them prior to making the request. The following line should be sufficient:
headers.add("Authorization", "Bearer " + authToken);
The code you mentioned has Http Basic authentication which consists of sending the credentials as username:password
pair encoded with Base64.
Upvotes: 2
Reputation: 371
You are encoding your token in Base64 and its already encoded, your code is based in this but in this example they are encoding a Basic Authorization header with (user:password) encoded
probe this
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer "+ authToken );
Upvotes: 1