복붙노트

[SPRING] RestTemplate 기본 또는 다이제스트 현재 httpclient (4.x) 인증

SPRING

RestTemplate 기본 또는 다이제스트 현재 httpclient (4.x) 인증

나는 (또는 Basic) RestTemplate과 httpclient (4.x)를 사용하여 Digest 대부분 (또는 Basic) 인증을 시도하고있다.

실제로이 작업을 수행하는 방법에 대한 관련 예제를 찾을 수 없기 때문에 다양한 httpclient 아티팩트를 연결하는 다양한 방법을 시도했지만 행운은 없습니다. 본질적으로 인증 헤더가 전혀 보내지지 않습니다.

현재 구현은 다음과 같습니다.

DefaultHttpClient newHttpClient = new DefaultHttpClient();
Credentials credentials = new UsernamePasswordCredentials( username, password );
AuthScope authScope = new AuthScope( host, port, AuthScope.ANY_REALM );
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials( authScope, credentials );
newHttpClient.setCredentialsProvider( credentialsProvider );

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory( newHttpClient );
restTemplate.setRequestFactory( requestFactory );

내가 잘못하고 있는게 있나요? 이것에 대한 작업 예제가 있습니까? 어떤 도움을 주셔서 감사합니다. 감사.

해결법

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

    1.선제 적 인증을 달성하기 위해 자신의 RequestFactory를 구현하십시오.

    선제 적 인증을 달성하기 위해 자신의 RequestFactory를 구현하십시오.

    public class PreEmptiveAuthHttpRequestFactory extends HttpComponentsClientHttpRequestFactory {
    
    public PreEmptiveAuthHttpRequestFactory(DefaultHttpClient client) {
        super(client);
    }
    
    @Override
    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
        AuthCache authCache = new BasicAuthCache();
        BasicScheme basicAuth = new BasicScheme();
        HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort());
        authCache.put(targetHost, basicAuth);
        BasicHttpContext localcontext = new BasicHttpContext();
        localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
    
        return localcontext;
    }
    }
    

    그런 다음 사용하십시오.

    HttpComponentsClientHttpRequestFactory requestFactory = new PreEmptiveAuthHttpRequestFactory( newHttpClient );
    

    희망이 도움이된다.

    사용자 이름과 암호를 설정하는 방법 (@ bifur의 의견에서 복사 됨)

    UserNamePasswordCredentials를 사용할 수 있습니다.

    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(getUsername(),getPassword()); 
    client.getCredentialsProvider().setCredentials(new AuthScope(getHost(), getPort(), AuthScope.ANY_REALM), credentials); 
    

    이전 공장에서 클라이언트를 사용하십시오.

    HttpComponentsClientHttpRequestFactory requestFactory = new PreEmptiveAuthHttpRequestFactory(client);
    
  2. ==============================

    2.최신 버전의 Spring과 HttpClient를 사용하여 기본 인증과 다이제스트 인증을 모두 수행하는 것이 매우 쉽습니다.

    최신 버전의 Spring과 HttpClient를 사용하여 기본 인증과 다이제스트 인증을 모두 수행하는 것이 매우 쉽습니다.

    참고 : 저는 Spring Boot 2.x.x (Spring Framework 5.x.x)와 HttpClient 4.5.x를 사용하고 있습니다.

    선점 형 또는 비 선점 형 (기본) 기본 또는 다이제스트 인증을 수행하도록 RestTemplate을 구성 할 수 있습니다.

    비 선점 기본 또는 다이제스트 인증 설정

    RestTemplate이 비 선점 (즉 초기에는 요청 요청을 수행) 기본 또는 다이제스트 인증을 사용하도록 설정하는 것은 동일합니다. HttpClient 라이브러리의 CredentialsProvider 클래스를 통해 사용자 이름과 암호를 제공하기 만하면됩니다.

    HttpClient는 초기 요청 (챌린지 요청)의 401 응답 헤더를 기반으로 서버가 사용중인 인증 유형을 자동으로 감지하므로 인증 유형별 구성을 수행 할 필요가 없습니다.

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        Credentials credentials = new UsernamePasswordCredentials(username, password);
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, credentials);
    
        HttpClient httpClient = HttpClients
                .custom()
                .setDefaultCredentialsProvider(credentialsProvider)
                .build();
    
        return builder
                .requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient))
                .build();
    }
    

    선제 적 기본 인증 설정

    선점 형 기본 인증을 사용하면 Spring이 즉시 지원할 수 있습니다. 사용자 이름과 암호 만 필요하므로 선점 기본 권한을 사용하여 요청 요청을 수행하는 데 드는 추가 비용을 제거하는 것이 좋습니다.

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder
                .basicAuthorization(username, password)
                .build();
    }
    

    선제 다이제스트 인증 설정

    Spring은 RestTemplate에 대한 선점 다이제스트 승인을 지원하지 않습니다. 다이제스트 인증은 적어도 하나의 요청 요청이 이루어져야하기 때문에 nonce 및 아마도 다른 서버가 생성 한 데이터 (예 : 불투명)를 사용자 이름과 비밀번호와 별도로 인증해야하기 때문에 인증해야합니다.

    이 점을 감안할 때 HttpClient의 라이브러리를 직접 사용해도 선점 다이제스트 인증을 사용할 수 있습니다. RestTemplate과 함께 digest preemptive auth를 사용하기를 원한다면 Spring 다이제스트 보호 애플리케이션에 연결할 때 몇 가지 문제가 발생할 수 있습니다.

    선불 다이제스트 승인을 사용하려면 이전 답변을 참조하십시오. 개인적으로 나는 발생할 수있는 복잡성과 문제점을 감안할 때 RestTemplate에 선점 다이제스트 승인을 사용하지 않을 것을 제안합니다. 선점 다이제스트 인증을 사용하는 주된 동기는 성능 목적을위한 것이므로 요청 당 많은 호출을하지 않는 한 비 선점 다이제스트 인증이 더 나은 옵션 일 수 있습니다.

    RestTemplate을 사용하여 요청을 보낼 때 인증 유형별 처리가 필요하지 않습니다. 선점 형 또는 비 선제 형 인증을 사용하는 경우 중요하지 않습니다. 요청을 전송하는 코드는 동일합니다.

    샘플 GET 요청

    String response = restTemplate.getForObject(url, String.class);
    JSONObject result = new JSONObject(response);
    

    샘플 POST 요청

    JSONObject body = new JSONObject();
    // populate body
    
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    
    HttpEntity<String> request = new HttpEntity<>(body, headers);
    String response = restTemplate.postForObject(url, request, String.class);
    JSONObject result = new JSONObject(response);
    
  3. ==============================

    3.나는 원래의 대답을 약간 수정했다 :

    나는 원래의 대답을 약간 수정했다 :

  4. from https://stackoverflow.com/questions/9376549/resttemplate-basic-or-digest-authentication-with-the-current-httpclient-4-x by cc-by-sa and MIT license