복붙노트

[SPRING] RestTemplate을 사용한 Spring 4.0.0 기본 인증

SPRING

RestTemplate을 사용한 Spring 4.0.0 기본 인증

현재 제 3 자 응용 프로그램과 지역보고 시스템을 통합하려고합니다. 기본 인증으로 REST 호출을 구현하고 싶지만 Spring 4.0.0에서는 문제가있다. 나는 잘 작동하는 간단한 해결책을 가지고있다 :

final RestTemplate restTemplate = new RestTemplate();
final String plainCreds = "username:password";
final byte[] plainCredsBytes = plainCreds.getBytes();
final byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
final String base64Creds = new String(base64CredsBytes);

final HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
final HttpEntity<String> request = new HttpEntity<String>(headers);

final ResponseEntity<MyDto> response = restTemplate.exchange("myUrl", HttpMethod.GET, request, MyDto.class);
final MyDto dot = response.getBody();

그러나 다음과 같은 방법으로 ClientHttpRequestFactory를 사용하기 위해 이것을 다시 쓰고 싶었습니다 :

final RestTemplate restTemplate = new RestTemplate(createSecureTransport("username", "password"));

private ClientHttpRequestFactory createSecureTransport(final String username, final String password) {
    final HttpClient client = new HttpClient();
    final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
    client.getState().setCredentials(new AuthScope(null, 9090, AuthScope.ANY_REALM), credentials);
    return new CommonsClientHttpRequestFactory(client);
}

Spring 4.0.0에서는 CommonsClientHttpRequestFactory 클래스가 더 이상 존재하지 않으므로이 코드는 컴파일되지 않습니다. 누군가 다른 해결책을 알고 있습니까? 나는이 REST 세계에서 아주 새로운 것이므로 어떤 도움을 주시면 감사하겠습니다.

해결법

  1. ==============================

    1.Spring 4 API를 점검하여 필요한 인터페이스, 즉 ClientHttpRequestFactory를 구현하는 클래스를 확인하는 것은 어떻습니까?

    Spring 4 API를 점검하여 필요한 인터페이스, 즉 ClientHttpRequestFactory를 구현하는 클래스를 확인하는 것은 어떻습니까?

    Javadoc에서 볼 수 있듯이, HttpComponentsClientHttpRequestFactory를 원할 가능성이 높습니다. HttpComponentsClientHttpRequestFactory는 Apache의 HttpComponents에서 클라이언트를 사용하며, 이전의 HonspClient의 후속 버전입니다.

  2. ==============================

    2.나는 이것이 낡은 질문이라는 것을 알고 있지만 나는 이것에 대한 해답을 찾고 있었다. RestTemplate을 구성 할 때 RestTemplate 인터셉터를 추가해야합니다. 주석 구성의 예는 다음과 같습니다.

    나는 이것이 낡은 질문이라는 것을 알고 있지만 나는 이것에 대한 해답을 찾고 있었다. RestTemplate을 구성 할 때 RestTemplate 인터셉터를 추가해야합니다. 주석 구성의 예는 다음과 같습니다.

    @Bean
    public RestTemplate restTemplate() {
    
        final RestTemplate restTemplate = new RestTemplate();
    
        restTemplate.setMessageConverters(Arrays.asList(
                new FormHttpMessageConverter(),
                new StringHttpMessageConverter()
        ));
        restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("client", "secret"));
    
        return restTemplate;
    }
    

    BasicAuthorizationInterceptor 용의 Javadoc입니다.

    나는 좋은 몇 시간 동안 이것에 붙어 있었다. 어쩌면 그것은 가까운 미래에 누군가를 도울 것입니다.

  3. ==============================

    3.http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/에서 HttpClient 4.3 수정 사항 :

    http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/에서 HttpClient 4.3 수정 사항 :

    Spring 3.0과 3.1, 그리고 현재 4.x는 Apache HTTP 라이브러리를 아주 잘 지원합니다.

    HttpClient 4 및 Spring 4를 사용하여 작업을 시작하겠습니다.

    RestTemplate에는 기본 인증을 지원하는 팩토리 인 HTTP 요청 팩토리가 필요합니다. 그러나 기존 HttpComponentsClientHttpRequestFactory를 직접 사용하는 것은 어려울 것입니다. RestTemplate의 아키텍처는 HttpContext를 잘 지원하지 않으면 서 설계 되었기 때문에 퍼즐의 중요 부분입니다. 그래서 HttpComponentsClientHttpRequestFactory를 서브 클래스 화하고 createHttpContext 메소드를 오버라이드해야합니다 : (GitHub의 soluvas-framework에서 가져옴)

    package org.soluvas.commons.util;
    
    import java.net.URI;
    
    import javax.annotation.Nullable;
    
    import org.apache.http.HttpHost;
    import org.apache.http.auth.AuthScope;
    import org.apache.http.auth.UsernamePasswordCredentials;
    import org.apache.http.client.AuthCache;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.protocol.HttpClientContext;
    import org.apache.http.impl.auth.BasicScheme;
    import org.apache.http.impl.client.BasicAuthCache;
    import org.apache.http.impl.client.BasicCredentialsProvider;
    import org.apache.http.protocol.HttpContext;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * From http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/
     * 
     * <p>And with that, everything is in place – the {@link RestTemplate} will now be able to support the Basic Authentication scheme; a simple usage pattern would be:
     * 
     * <pre>
     * final AuthHttpComponentsClientHttpRequestFactory requestFactory = new AuthHttpComponentsClientHttpRequestFactory(
     *                  httpClient, host, userName, password);
     * final RestTemplate restTemplate = new RestTemplate(requestFactory);
     * </pre>
     *   
     * And the request:
     *
     * <pre>
     * restTemplate.get("http://localhost:8080/spring-security-rest-template/api/foos/1", Foo.class);
     * </pre>
     * 
     * @author anton
     */
    public class AuthHttpComponentsClientHttpRequestFactory extends
            HttpComponentsClientHttpRequestFactory {
    
        protected HttpHost host;
        @Nullable
        protected String userName;
        @Nullable
        protected String password;
    
        public AuthHttpComponentsClientHttpRequestFactory(HttpHost host) {
            this(host, null, null);
        }
    
        public AuthHttpComponentsClientHttpRequestFactory(HttpHost host, @Nullable String userName, @Nullable String password) {
            super();
            this.host = host;
            this.userName = userName;
            this.password = password;
        }
    
        public AuthHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpHost host) {
            this(httpClient, host, null, null);
        }
    
        public AuthHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpHost host, 
                @Nullable String userName, @Nullable String password) {
            super(httpClient);
            this.host = host;
            this.userName = userName;
            this.password = password;
        }
    
        @Override
        protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
           // Create AuthCache instance
            AuthCache authCache = new BasicAuthCache();
            // Generate BASIC scheme object and add it to the local auth cache
            BasicScheme basicAuth = new BasicScheme();
            authCache.put(host, basicAuth);
    
            // Add AuthCache to the execution context
            HttpClientContext localcontext = HttpClientContext.create();
            localcontext.setAuthCache(authCache);
    
            if (userName != null) {
                BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
                credsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(userName, password));
                localcontext.setCredentialsProvider(credsProvider);
            }
            return localcontext;        
        }
    
    }
    

    HttpContext를 생성 할 때 기본 인증 지원이 내장되어 있습니다. HttpClient 4.x를 사용하여 선점 기본 인증을 수행하는 것은 약간의 부담입니다. 인증 정보가 캐싱되고 이 인증 캐시를 설정하는 것은 매우 수동적이고 직관적이지 않습니다.

    그리고 그걸로 모든 것이 제자리에 있습니다. 이제 RestTemplate이 기본 인증 구성표를 지원할 수있게 될 것입니다. 간단한 사용 패턴은 다음과 같습니다.

    final AuthHttpComponentsClientHttpRequestFactory requestFactory =
        new AuthHttpComponentsClientHttpRequestFactory(
                    httpClient, host, userName, password);
    final RestTemplate restTemplate = new RestTemplate(requestFactory);
    

    그리고 요청 :

    restTemplate.get(
        "http://localhost:8080/spring-security-rest-template/api/foos/1",
        Foo.class);
    

    REST 서비스 자체를 보호하는 방법에 대한 자세한 설명은이 기사를 참조하십시오.

  4. ==============================

    4.Spring 4.3.1부터 RestTemplate에서 사용되는 기본 http 클라이언트와 독립적 인 BasicAuthorizationInterceptor를 사용하는 간단한 방법이 있습니다.

    Spring 4.3.1부터 RestTemplate에서 사용되는 기본 http 클라이언트와 독립적 인 BasicAuthorizationInterceptor를 사용하는 간단한 방법이 있습니다.

    Spring-boot에서 RestTemplateBuilder를 사용하여 BasicAuthorizationInterceptor를 RestTemplate에 추가하는 예제입니다.

    @Configuration
    public class AppConfig {
    
        @Bean
        public RestTemplate myRestTemplate(RestTemplateBuilder builder) {
            return builder
                    .rootUri("http://my.cool.domain/api/")
                    .basicAuthorization("login", "password")
                    .build();
        }
    
    }
    

    이 방법으로 myRestTemplate 빈 인스턴스를 사용하여 전송 된 요청에는 지정된 기본 인증 헤더가 포함됩니다. 따라서 동일한 RestTemplate 빈 인스턴스를 사용하여 외부 도메인에 요청을 보내지 않도록주의하십시오. rootUri는 부분적으로 이것으로부터 보호하지만 RestTemplate 인스턴스를 사용하여 요청할 때 항상 절대 URL을 전달할 수 있으므로주의하십시오!

    Spring-boot를 사용하지 않는다면, 수동으로이 인터셉터를 RestTemplate에 추가 할 수도 있습니다.

  5. ==============================

    5.단순한 복잡한 것을 선호하는 경우 헤더 만 설정하면됩니다.

    단순한 복잡한 것을 선호하는 경우 헤더 만 설정하면됩니다.

        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString("myuser:mypass".getBytes(Charset.forName("UTF-8"))));
        HttpEntity<SomeBody> myRequest = new HttpEntity<>(mybody, headers);
        restTemplate.postForEntity(someUrl, myRequest, null);
    

    JDK와 함께 제공되는 인코딩이 너무 장황하면 다른 Base64 라이브러리가있을 것입니다.

  6. ==============================

    6.사용자 지정 나머지 템플릿에 대한 기본 인증을 설정하는 또 다른 솔루션이 있습니다.

    사용자 지정 나머지 템플릿에 대한 기본 인증을 설정하는 또 다른 솔루션이 있습니다.

    RestTemplate restTemplate = new RestTemplate();
        HttpHost proxy =null;
        RequestConfig config=null;
        String credentials = this.env.getProperty("uname") + ":" + this.env.getProperty("pwd");
        String encodedAuthorization = Base64.getEncoder().encodeToString(credentials.getBytes());
    
        Header header = new BasicHeader(HttpHeaders.AUTHORIZATION, "Basic " + encodedAuthorization);
        List<Header> headers = new ArrayList<>();
        headers.add(header);
        // if we need proxy
        if(Boolean.valueOf(env.getProperty("proxyFlag"))){
            proxy = new HttpHost(this.env.getProperty("proxyHost"), Integer.parseInt(env.getProperty("proxyPort")), "http");
            config= RequestConfig.custom().setProxy(proxy).build();
        }else{
            config= RequestConfig.custom().build();
        }
    
    
        CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config)
                .setDefaultHeaders(headers).build();
    
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
        restTemplate.setRequestFactory(factory);
    
        return restTemplate;
    
  7. from https://stackoverflow.com/questions/21998405/spring-4-0-0-basic-authentication-with-resttemplate by cc-by-sa and MIT license