[java] HttpClient를 사용하는 Java의 Http 기본 인증?

Java 에서이 curl 명령의 기능을 모방하려고합니다.

curl --basic --user username:password -d "" http://ipaddress/test/login

Commons HttpClient 3.0을 사용하여 다음을 작성했지만 어떻게 든 500 Internal Server Error서버에서 가져 왔습니다. 내가 잘못하고 있는지 말해 줄 수 있습니까?

public class HttpBasicAuth {

    private static final String ENCODING = "UTF-8";

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {

            HttpClient client = new HttpClient();

            client.getState().setCredentials(
                    new AuthScope("ipaddress", 443, "realm"),
                    new UsernamePasswordCredentials("test1", "test1")
                    );

            PostMethod post = new PostMethod(
                    "http://address/test/login");

            post.setDoAuthentication( true );

            try {
                int status = client.executeMethod( post );
                System.out.println(status + "\n" + post.getResponseBodyAsString());
            } finally {
                // release any connection resources used by the method
                post.releaseConnection();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
   } 

그리고 나중에 Commons HttpClient 4.0.1을 시도했지만 여전히 같은 오류가 발생했습니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;


public class HttpBasicAuth {

    private static final String ENCODING = "UTF-8";

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try {
            DefaultHttpClient httpclient = new DefaultHttpClient();

            httpclient.getCredentialsProvider().setCredentials(
                    new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
                    new UsernamePasswordCredentials("test1", "test1"));

            HttpPost httppost = new HttpPost("http://host:post/test/login");

            System.out.println("executing request " + httppost.getRequestLine());
            HttpResponse response;
            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            if (entity != null) {
                System.out.println("Response content length: " + entity.getContentLength());
            }
            if (entity != null) {
                entity.consumeContent();
            }

            httpclient.getConnectionManager().shutdown();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}



답변

이것을 시도 했습니까 (HttpClient 버전 4 사용).

String encoding = Base64Encoder.encode(user + ":" + pwd);
HttpPost httpPost = new HttpPost("http://host:post/test/login");
httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoding);

System.out.println("executing request " + httpPost.getRequestLine());
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();


답변

좋아,이게 작동합니다. 누군가가 그것을 원한다면, 여기 나를 위해 작동하는 버전이 있습니다 🙂

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;


public class HttpBasicAuth {

    public static void main(String[] args) {

        try {
            URL url = new URL ("http://ip:port/login");
            String encoding = Base64.getEncoder().encodeToString(("test1:test1").getBytes(‌"UTF‌​-8"​));

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setRequestProperty  ("Authorization", "Basic " + encoding);
            InputStream content = (InputStream)connection.getInputStream();
            BufferedReader in   =
                new BufferedReader (new InputStreamReader (content));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }

    }

}


답변

이것은 Base64 인코딩과 관련하여 일부 변경 사항이 적용된 위의 답변의 코드입니다. 아래 코드는 컴파일됩니다.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.codec.binary.Base64;


public class HttpBasicAuth {

    public static void main(String[] args) {

        try {
            URL url = new URL ("http://ip:port/login");

            Base64 b = new Base64();
            String encoding = b.encodeAsString(new String("test1:test1").getBytes());

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setRequestProperty  ("Authorization", "Basic " + encoding);
            InputStream content = (InputStream)connection.getInputStream();
            BufferedReader in   =
                new BufferedReader (new InputStreamReader (content));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}


답변

작은 업데이트-누군가에게 희망적으로 유용한-내 프로젝트에서 저에게 효과적입니다.

  • Robert Harder의 멋진 Public Domain 클래스 Base64.java를 사용합니다 (Robert-Code availble here : Base64- 다운로드하여 패키지에 넣습니다).

  • 인증을 통해 파일 (이미지, 문서 등)을 다운로드하고 로컬 디스크에 쓰기

예:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpBasicAuth {

public static void downloadFileWithAuth(String urlStr, String user, String pass, String outFilePath) {
    try {
        // URL url = new URL ("http://ip:port/download_url");
        URL url = new URL(urlStr);
        String authStr = user + ":" + pass;
        String authEncoded = Base64.encodeBytes(authStr.getBytes());

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setDoOutput(true);
        connection.setRequestProperty("Authorization", "Basic " + authEncoded);

        File file = new File(outFilePath);
        InputStream in = (InputStream) connection.getInputStream();
        OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        for (int b; (b = in.read()) != -1;) {
            out.write(b);
        }
        out.close();
        in.close();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}
}


답변

다음은 몇 가지 사항입니다.

  • HttpClient 4로 업그레이드하는 것을 고려할 수 있습니다 (일반적으로 말할 수 있다면 버전 3이 여전히 적극적으로 지원되지 않는다고 생각합니다).

  • 500 상태 코드는 서버 오류이므로 서버에서 무엇을 말하고 있는지 확인하는 것이 좋습니다 (인쇄중인 응답 본문의 단서가 있습니까?). 클라이언트가 원인 일 수 있지만 서버는 이런 식으로 실패하지 않아야합니다 (요청이 올바르지 않은 경우 4xx 오류 코드가 더 적합합니다).

  • 나는 setDoAuthentication(true)기본값 이라고 생각 합니다 (확실하지 않음). 시도하는 데 유용한 것은 선점 인증이 더 잘 작동한다는 것입니다.

    client.getParams().setAuthenticationPreemptive(true);

그렇지 않으면 curl -d ""Java에서하고있는 것과 의 주요 차이점은 Content-Length: 0curl 외에도 curl도 전송 한다는 것 Content-Type: application/x-www-form-urlencoded입니다. 디자인 측면에서 POST어쨌든 귀하의 요청이 있는 엔터티를 보내야 합니다.


답변

위의 모든 답변에 감사드립니다.하지만 저에게는 Base64Encoder 클래스를 찾을 수 없으므로 어쨌든 내 길을 정리합니다.

public static void main(String[] args) {
    try {
        DefaultHttpClient Client = new DefaultHttpClient();

        HttpGet httpGet = new HttpGet("https://httpbin.org/basic-auth/user/passwd");
        String encoding = DatatypeConverter.printBase64Binary("user:passwd".getBytes("UTF-8"));
        httpGet.setHeader("Authorization", "Basic " + encoding);

        HttpResponse response = Client.execute(httpGet);

        System.out.println("response = " + response);

        BufferedReader breader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuilder responseString = new StringBuilder();
        String line = "";
        while ((line = breader.readLine()) != null) {
            responseString.append(line);
        }
        breader.close();
        String repsonseStr = responseString.toString();

        System.out.println("repsonseStr = " + repsonseStr);

    } catch (IOException e) {
        e.printStackTrace();
    }

}

한가지 더, 나는 또한 시도했다

Base64.encodeBase64String("user:passwd".getBytes());

거의 같은 문자열을 반환하기 때문에 작동하지 않습니다

DatatypeConverter.printBase64Binary()

“\ r \ n”으로 끝나면 서버는 “잘못된 요청”을 반환합니다.

또한 다음 코드도 작동하지만 실제로 먼저 정렬해야하지만 어떤 이유로 일부 클라우드 환경에서는 작동하지 않습니다 (알고 싶다면 중국어 클라우드 서비스입니다). 따라서 HttpClient 자격 증명 대신 http 헤더를 사용해야합니다.

public static void main(String[] args) {
    try {
        DefaultHttpClient Client = new DefaultHttpClient();
        Client.getCredentialsProvider().setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials("user", "passwd")
        );

        HttpGet httpGet = new HttpGet("https://httpbin.org/basic-auth/user/passwd");
        HttpResponse response = Client.execute(httpGet);

        System.out.println("response = " + response);

        BufferedReader breader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuilder responseString = new StringBuilder();
        String line = "";
        while ((line = breader.readLine()) != null) {
            responseString.append(line);
        }
        breader.close();
        String responseStr = responseString.toString();
        System.out.println("responseStr = " + responseStr);

    } catch (IOException e) {
        e.printStackTrace();
    }
}


답변

헤더 배열을 사용하는 동안

String auth = Base64.getEncoder().encodeToString(("test1:test1").getBytes());
Header[] headers = {
    new BasicHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()),
    new BasicHeader("Authorization", "Basic " +auth)
};