Spring restTemplate을 사용한 REST API의 기본 인증


86

나는 RestTemplate과 기본적으로 REST API에서도 완전히 새로운 것입니다. Jira REST API를 통해 내 애플리케이션에서 일부 데이터를 검색하고 싶지만 401 Unauthorised가 반환됩니다. jira rest api 문서 에 대한 기사를 찾았 지만 예제에서는 curl과 함께 명령 줄 방식을 사용하므로이를 Java로 다시 작성하는 방법을 모릅니다. 다시 작성하는 방법에 대한 제안이나 조언을 주시면 감사하겠습니다.

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

스프링 나머지 템플릿을 사용하여 자바로. 여기서 ZnJlZDpmcmVk는 사용자 이름 : 암호의 base64 인코딩 문자열입니다. 대단히 감사합니다.



2
curl은 기본적으로 인증을 지원하므로 사용자 이름과 암호를 알려 주기만하면 curl -u fred:fred됩니다. 복잡한 수동 헤더가 필요하지 않습니다. Spring도 마찬가지입니다.
divanov

답변:


150

이 사이트예에서 발췌 헤더 값을 채우고 헤더를 템플릿에 전달하는 것이 가장 자연스러운 방법이라고 생각합니다.

이것은 헤더를 채우는 것입니다 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);

그리고 이것은 헤더를 REST 템플릿에 전달하는 것입니다.

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

1
감사합니다-이것은 나를 위해 일했습니다. org.apache.commons.codec.binary.Base64 클래스를 사용하고 싶지 않고 대신 android Base64 클래스를 사용하려면 import android.util.Base64 ;, 한 줄 위에 다음과 같이 입력합니다. byte [] base64CredsBytes = Base64.encode (plainCredsBytes, Base64.DEFAULT);
Simon

@jhadesdev 안녕하세요, 이것은 GET 요청을 수행 할 때 저에게 효과적이었습니다. 게시물에서 403을 제공하지 못하지만. 도와주세요?
Stefano Cazzola 2015

8
자바 8은 Base64.getMimeEncoder ()를 사용할 수 encodeToString ().
매트 Broekhuis

95

spring-boot RestTemplateBuilder를 사용할 수 있습니다.

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

문서 보기

(SB 2.1.0 이전에는 #basicAuthorization)


1
당신은 내 하루를 구했습니다. 감사합니다.
riccardo.cardin 2017

4
감사! 이것이 가장 빠르고 쉬운 방법입니다.
Rajkishan Swami

1
예. 이것이 가장 빠른 방법입니다. 추가 종속성이 필요하지 않습니다.
Janath

3
#basicAuthentication (문자열 이름, 문자열 암호)에 찬성 2.1.0 이후 @deprecated
rjdkolb

2
를 통해 전송되는 모든 요청에 ​​인증 헤더를 추가하므로 좋은 솔루션이 아닙니다 RestTemplate.
attacomsian

22

(아마도) spring-boot를 가져 오지 않는 가장 쉬운 방법입니다.

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

2
인터셉터를 사용하면 스트리밍이 더 이상 작동하지 않습니다. 그 이유는 다음과 같습니다 exchange().-> doExecute(),-> createRequest(),-> InterceptingHttpAccessor.getRequestFactory()( RestTemplate확장 이후 InterceptingHttpAccessor). 인터셉터가 있으면를 getRequestFactory()반환하여 s InterceptingClientHttpRequestFactory를 만듭니다 InterceptingClientHttpRequest. 이들은 입력 스트림을 byte []로 변환하는 AbstractBufferingClientHttpRequest`를 확장합니다 (인터셉터로 전달). 따라서 InputStream은 실제로 스트리밍되지 않습니다.
mconner

17

Spring 5.1부터 사용할 수 있습니다. HttpHeaders.setBasicAuth

기본 승인 헤더를 만듭니다.

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

RestTemplate에 헤더를 전달합니다.

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

문서 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpHeaders.html#setBasicAuth-java.lang.String-java.lang.String-


17

TestRestTemplate다음과 같이 Spring Boot의 구현을 참조하십시오 .

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

특히 다음과 같이 addAuthentication () 메서드를 참조하십시오.

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));
}

마찬가지로 RestTemplate쉽게 만들 수 있습니다.

TestRestTemplate다음과 같이 상속 으로 :

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


첫 번째 링크는 404로 연결됩니다
Zarremgregarrok 19 년

15

기본 HTTP 인증을 추가하는 방법에는 여러 가지가 있습니다. RestTemplate .

1. 단일 요청

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();
}

Spring 5.1이상을 사용하는 경우 더 이상 권한 헤더를 수동으로 설정할 필요가 없습니다. headers.setBasicAuth()대신 방법을 사용하십시오 .

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

2. 요청 그룹의 경우

@Service
public class RestService {

    private final RestTemplate restTemplate;

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

   // use `restTemplate` instance here
}

3. 모든 요청에 ​​대해

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

도움이 되었기를 바랍니다.


최고의 답변입니다. 각각은 친절합니다.
Rishi

6

다음과 같이 인스턴스화하는 대신 :

TestRestTemplate restTemplate = new TestRestTemplate();

다음과 같이하십시오.

TestRestTemplate restTemplate = new TestRestTemplate(user, password);

그것은 나를 위해 작동합니다, 나는 그것이 도움이되기를 바랍니다!


TestRestTemplate은 1.3.x 버전으로 업그레이드 스프링 부팅 후 작동하지 않는 것
비벡 세티을

1
이것은 코드를 릴리스하지 않고 단위 테스트에 사용되어야하지 않습니까?
David Bradley

0

사용 setBasicAuth자격 증명을 정의 할 수

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

그런 다음 원하는대로 요청을 작성하십시오.

예:

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.