在 Spring RestTemplate 中设置 Authorization 标头

Ste*_*anS 5 spring authorization resttemplate

我试图在 Spring 的 RestTemplate 的帮助下访问 RestAPI-Endpoint

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();
}
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

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");
Run Code Online (Sandbox Code Playgroud)

still leads to the same HttpClientErrorException: 403 Forbidden

Update2

I answered my question! (short version: UserAgent required. final code in anwser)

Ste*_*anS 12

这个特定的服务器需要一个 UserAgent!值可以是任何值,但它必须存在!

所以最终版本是:

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();
}
Run Code Online (Sandbox Code Playgroud)


Fer*_*nix 1

您正在使用 Base64 编码您的令牌,并且它已经编码,您的代码基于,但在本示例中,它们使用(用户:密码)编码的基本授权标头进行编码

探测这个

 HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    headers.add("Authorization", "Bearer "+ authToken );
Run Code Online (Sandbox Code Playgroud)