Xác thực cơ bản cho REST API bằng cách sử dụng Spring restTemplate


83

Tôi hoàn toàn mới trong RestTemplate và về cơ bản cũng có trong API REST. Tôi muốn truy xuất một số dữ liệu trong ứng dụng của mình thông qua Jira REST API, nhưng nhận lại 401 Trái phép. Tìm thấy và bài viết trên tài liệu jira rest api nhưng không thực sự biết cách viết lại nó thành java vì ví dụ sử dụng dòng lệnh với curl. Tôi sẽ đánh giá cao bất kỳ đề xuất hoặc lời khuyên nào về cách viết lại:

curl -D- -X GET -H "Authorization: Basic ZnJlZDpmcmVk" -H "Content-Type: application/json" "http://kelpie9:8081/rest/api/2/issue/QA-31"

vào java bằng cách sử dụng mẫu phần còn lại mùa xuân. Trong đó ZnJlZDpmcmVk là một chuỗi tên người dùng: mật khẩu được mã hóa base64. Cảm ơn rât nhiều.



2
curl hỗ trợ xác thực ngay lập tức, bạn chỉ cần cho nó biết tên người dùng và mã xác nhận curl -u fred:fred, không cần phải có các tiêu đề thủ công rườm rà . Mùa Xuân cũng vậy.
divanov

Câu trả lời:


148

Lấy từ ví dụ trên trang web này , tôi nghĩ rằng đây sẽ là cách làm tự nhiên nhất, bằng cách điền vào giá trị tiêu đề và chuyển tiêu đề vào mẫu.

Đây là để điền vào tiêu đề Authorization:

String plainCreds = "willie:p@ssword";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);

HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);

Và điều này là để chuyển tiêu đề cho mẫu REST:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
Account account = response.getBody();

1
Cảm ơn - điều này đã làm việc cho tôi. Tôi phải chỉ ra rằng nếu bạn không muốn sử dụng lớp org.apache.commons.codec.binary.Base64 và bạn muốn sử dụng lớp Base64 android thay thế: import android.util.Base64 ;, bạn có thể thay thế một dòng ở trên với dòng này: byte [] base64CredsBytes = Base64.encode (trơnCredsBytes, Base64.DEFAULT);
Simon

@jhadesdev Xin chào, điều này phù hợp với tôi khi thực hiện yêu cầu GET. Mặc dù nó không đưa ra 403 khi đăng. Bạn có thể giúp tôi được không?
Stefano Cazzola

7
java 8 bạn có thể sử dụng Base64.getMimeEncoder () encodeToString ().
Matt Broekhuis

92

Bạn có thể sử dụng Spring-boot RestTemplateBuilder

@Bean
RestOperations rest(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.basicAuthentication("user", "password").build();
}

Xem tài liệu

(trước SB 2.1.0 nó là #basicAuthorization)


1
Bạn đã cứu ngày của tôi. Cảm ơn rất nhiều.
riccardo.cardin

4
Cảm ơn! Đây là cách nhanh nhất và dễ dàng nhất.
Rajkishan Swami

1
Đúng. đây là cách nhanh nhất. Không có phụ thuộc bổ sung được yêu cầu.
Janath

3
@deprecated kể từ 2.1.0 ủng hộ #basicAuthentication (Tên người dùng chuỗi, Mật khẩu chuỗi)
rjdkolb 13/12/18

1
Nó không phải là một giải pháp tốt vì nó sẽ thêm một tiêu đề ủy quyền cho mỗi và mọi yêu cầu được gửi qua RestTemplate.
attacomsian

22

(có thể) cách dễ nhất mà không cần nhập Spring-boot.

restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("user", "password"));

2
Hãy lưu ý rằng việc sử dụng các trình đánh chặn có hậu quả là tính năng phát trực tuyến không còn hoạt động. Đây là lý do tại sao: exchange()-> doExecute(), -> createRequest(), -> InterceptingHttpAccessor.getRequestFactory()(kể từ khi RestTemplatemở rộng InterceptingHttpAccessor). Nếu có các dấu chặn, getRequestFactory()trả về an InterceptingClientHttpRequestFactory, tạo ra InterceptingClientHttpRequests. Những điều này mở rộng AbstractBufferingClientHttpRequest`, chuyển đổi luồng đầu vào thành byte [] (để chuyển giao cho các bộ đánh chặn). Vì vậy, một InputStream không thực sự được truyền trực tuyến.
mconner

17

Kể từ Spring 5.1, bạn có thể sử dụng HttpHeaders.setBasicAuth

Tạo tiêu đề Ủy quyền Cơ bản:

String username = "willie";
String password = ":p@ssword";
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(username, password);
...other headers goes here...

Chuyển các tiêu đề vào RestTemplate:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
Account account = response.getBody();

Tài liệu: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpHeaders.html#setBasicAuth-java.lang.String-java.lang.String-


17

Tham khảo cách TestRestTemplatetriển khai của Spring Boot như sau:

https://github.com/spring-projects/spring-boot/blob/v1.2.2.RELEASE/spring-boot/src/main/java/org/springframework/boot/test/TestRestTemplate.java

Đặc biệt, hãy xem phương thức addAuthentication () như sau:

private void addAuthentication(String username, String password) {
    if (username == null) {
        return;
    }
    List<ClientHttpRequestInterceptor> interceptors = Collections
            .<ClientHttpRequestInterceptor> singletonList(new BasicAuthorizationInterceptor(
                    username, password));
    setRequestFactory(new InterceptingClientHttpRequestFactory(getRequestFactory(),
            interceptors));
}

Tương tự, bạn có thể tự làm một RestTemplatecách dễ dàng

bằng kế thừa như TestRestTemplatesau:

https://github.com/izeye/samples-spring-boot-bragets/blob/rest-and-actuator-with-security/src/main/java/samples/springboot/util/BasicAuthRestTemplate.java


các dẫn liên kết đầu tiên 404
Zarremgregarrok

14

Có nhiều cách để thêm xác thực HTTP cơ bản vào RestTemplate.

1. Đối với một yêu cầu duy nhất

try {
    // request url
    String url = "https://jsonplaceholder.typicode.com/posts";

    // create auth credentials
    String authStr = "username:password";
    String base64Creds = Base64.getEncoder().encodeToString(authStr.getBytes());

    // create headers
    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Basic " + base64Creds);

    // create request
    HttpEntity request = new HttpEntity(headers);

    // make a request
    ResponseEntity<String> response = new RestTemplate().exchange(url, HttpMethod.GET, request, String.class);

    // get JSON response
    String json = response.getBody();

} catch (Exception ex) {
    ex.printStackTrace();
}

Nếu bạn đang sử dụng Spring 5.1trở lên, bạn không cần đặt tiêu đề ủy quyền theo cách thủ công nữa. Sử dụng headers.setBasicAuth()phương pháp thay thế:

// create headers
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("username", "password");

2. Đối với một nhóm yêu cầu

@Service
public class RestService {

    private final RestTemplate restTemplate;

    public RestService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder
                .basicAuthentication("username", "password")
                .build();
    }

   // use `restTemplate` instance here
}

3. Đối với mỗi và mọi yêu cầu

@Bean
RestOperations restTemplateBuilder(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.basicAuthentication("username", "password").build();
}

Tôi hy vọng nó sẽ giúp!


Câu trả lời tốt nhất. Mỗi thứ đều tốt.
Rishi

6

Thay vì khởi tạo như sau:

TestRestTemplate restTemplate = new TestRestTemplate();

Chỉ cần làm như thế này:

TestRestTemplate restTemplate = new TestRestTemplate(user, password);

Nó hoạt động cho tôi, tôi hy vọng nó sẽ giúp!


TestRestTemplate dường như không làm việc sau khi khởi động mùa xuân nâng cấp lên 1.3.x
Vivek Sethi

1
Điều này không phải được sử dụng cho các bài kiểm tra đơn vị không phát hành mã?
David Bradley

0

Sử dụng setBasicAuthđể xác định thông tin đăng nhập

HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("myUsername", myPassword);

Sau đó, tạo yêu cầu như bạn muốn.

Thí dụ:

HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, 
request, String.class);
String body = response.getBody();

Dublicate of stackoverflow.com/a/53394971 câu trả lời
Grigory Kislin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.