HttpClient를 사용한 Java에서의 Http Basic 인증
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 = Base64.getEncoder().encodeToString((user + ":" + pwd).getBytes());
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를 사용합니다(Thanks Robert - Code avail 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 ""
자바에서 하고 있는 일은Content-Length: 0
, curl도 송신합니다.Content-Type: application/x-www-form-urlencoded
설계 측면에서는 엔티티와 함께 엔티티를 보내야 합니다.POST
요청해 주세요.
헤더 배열 사용 중
String auth = Base64.getEncoder().encodeToString(("test1:test1").getBytes());
Header[] headers = {
new BasicHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()),
new BasicHeader("Authorization", "Basic " +auth)
};
위의 답변은 모두 감사합니다만, 저는 Base64 Encoder 클래스를 찾을 수 없기 때문에, 어떻게든 방법을 정합니다.
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"로 종료하면 서버는 "bad request"를 반환합니다.
또한 다음 코드도 작동합니다. 사실 먼저 분류합니다만, 어떤 이유로 인해 일부 클라우드 환경에서는 작동하지 않습니다(sae.sina.com.cn는 중국 클라우드 서비스입니다).따라서 HttpClient credential 대신 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();
}
}
Base64 고유의 콜을 실행하지 않고 HTTP POST를 사용하여 로그인하는 간단한 방법은 HTTP Client Basic Credentials Provider를 사용하는 것입니다.
import java.io.IOException;
import static java.lang.System.out;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
//code
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user, password);
provider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
HttpResponse response = client.execute(new HttpPost("http://address/test/login"));//Replace HttpPost with HttpGet if you need to perform a GET to login
int statusCode = response.getStatusLine().getStatusCode();
out.println("Response Code :"+ statusCode);
HttpClient의 경우 항상 HttpRequest를 사용합니다.예를 들어 인터셉터
httclient.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(HttpRequest arg0, HttpContext context) throws HttpException, IOException {
AuthState state = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
if (state.getAuthScheme() == null) {
BasicScheme scheme = new BasicScheme();
CredentialsProvider credentialsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
Credentials credentials = credentialsProvider.getCredentials(AuthScope.ANY);
if (credentials == null) {
System.out.println("Credential >>" + credentials);
throw new HttpException();
}
state.setAuthScope(AuthScope.ANY);
state.setAuthScheme(scheme);
state.setCredentials(credentials);
}
}
}, 0);
작은 변경에도 HttpBasicAuth가 기능합니다.
maven 의존성을 사용합니다.
<dependency> <groupId>net.iharder</groupId> <artifactId>base64</artifactId> <version>2.3.8</version> </dependency>
작은 변화
String encoding = Base64.encodeBytes ((user + ":" + passwd).getBytes());
언급URL : https://stackoverflow.com/questions/3283234/http-basic-authentication-in-java-using-httpclient
'programing' 카테고리의 다른 글
호출하지 않고 실행 중인 계산 함수 (0) | 2022.08.11 |
---|---|
for 루프의 현재 항목을 vue.js 2의 메서드에 전달하려면 어떻게 해야 합니까? (0) | 2022.08.11 |
현재 루트/URL에 다이내믹 브레드 크럼 컴포넌트 베이스를 구축하려면 어떻게 해야 합니까? (0) | 2022.08.11 |
Vue3에서 어레이 타입의 프로펠러 재렌더링 회피 (0) | 2022.08.11 |
Vuej에서 소품 변경 보기 (0) | 2022.08.10 |