Jersey Client를 사용하여 자체 서명 된 SSL 인증서 무시
Jersey 클라이언트 라이브러리를 사용하여 jboss에서 실행되는 나머지 서비스에 대해 테스트를 실행하고 있습니다. 자체 서명 된 인증서를 사용하여 서버 (localhost에서 실행)에 https가 제대로 설정되어 있습니다.
그러나 https URL로 테스트를 때마다 다음 오류가 발생합니다.
com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:131)
at com.sun.jersey.api.client.Client.handle(Client.java:629)
at com.sun.jersey.oauth.client.OAuthClientFilter.handle(OAuthClientFilter.java:137)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:601)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:459)
at test.helper.Helper.sendSignedRequest(Helper.java:174)
... And so on
내 자체 서명 인증서가 Java 키 저장소에 있기 때문에 때문에 알고 있습니다. 내가 만들 수있는 방법이 Client
있나요? SSL 인증서의 유효성을 확인하고 단지에 관계없이 사용합니까?
이 코드는 테스트 서버에 설치 실행 새 테스트 서버를 추가 할 때마다 새로운 테스트 서버를 추가해야합니다.
전화를 거는 코드는 다음과 가변적입니다.
OAuthParameters params = new OAuthParameters();
// baseline OAuth parameters for access to resource
params.signatureMethod(props.getProperty("signature_method"));
params.consumerKey(props.getProperty("consumer_key"));
params.setToken(props.getProperty("token"));
params.setVersion("1.0");
params.nonce();
// OAuth secrets to access resource
OAuthSecrets secrets = new OAuthSecrets();
secrets.consumerSecret(props.getProperty("consumer_secret"));
secrets.setTokenSecret(props.getProperty("token_secret"));
// Jersey client to make REST calls to token services
Client client = Client.create();
// OAuth test server resource
WebResource resource = client.resource(props.getProperty("url"));
// if parameters and secrets remain static, filter cab be added to each web resource
OAuthClientFilter filter = new OAuthClientFilter(client.getProviders(), params, secrets);
// filter added at the web resource level
resource.addFilter(filter);
WebResource.Builder wbr = resource.getRequestBuilder().accept(props.getProperty("accept"));
return wbr.get(ClientResponse.class);
어떤 도움도 대단히 감사하겠습니다.
일부 오래된 stackoverflow 질문을 검색하고 트롤링 한 후 이전에 질문 한 SO 질문에서 해결을 찾았습니다.
내가 다루는 코드는 다음과 가변적입니다.
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){return null;}
public void checkClientTrusted(X509Certificate[] certs, String authType){}
public void checkServerTrusted(X509Certificate[] certs, String authType){}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
;
}
Jersey 2. * (2.7에서 테스트 됨) 및 Java 8 :
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public static Client ignoreSSLClient() throws Exception {
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
}}, new java.security.SecureRandom());
return ClientBuilder.newBuilder()
.sslContext(sslcontext)
.hostnameVerifier((s1, s2) -> true)
.build();
}
나는 동일한 문제가 발생하는 것입니다. 즉, 위와 동일한 TrustManager 및 SSLContext 코드를 사용하는 클라이언트가 특수 속성으로 생성 변경되었습니다.
ClientConfig config = new DefaultClientConfig();
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(
new HostnameVerifier() {
@Override
public boolean verify( String s, SSLSession sslSession ) {
// whatever your matching policy states
}
}
));
Client client = Client.create(config);
이 코드는 테스트 서버에 설치 실행 새 테스트 서버를 추가 할 때마다 새로운 테스트 서버를 추가해야합니다.
(본인이 아니라면이 질문을 읽는 다른 사람이 애플리케이션에 제안 된 안전하지 않은 신뢰 관리자를 복사하여 거기에있는 것입니다). 마감일이 폐쇄 될 때 이런 종류의 코드를 제거하는 것을 잊기 만 할 수 있습니다. 문제로 인해 때문입니다.
테스트 서버가있을 때마다 새 인증서를 추가해야 할 것이 걱정할 자신만의 작은 CA를 만들고 해당 CA를 사용하는 테스트 서버에 대한 모든 인증서를 발급 한 다음이 CA 인증서를 클라이언트 신뢰 저장소로 가져옵니다. (로컬 컬 한 환경에서 온라인 인증서 해지와 같은 일을 처리하지 않는 것이 좋습니다.)
이를 수행하는 데 도움이되는 도구가 있습니다 (예 : TinyCA 또는 XCA) .
나는 stackoverflow를 처음 사용하고 다른 사람들의 답변에 대해 언급 한 것이 떨어지기 때문에 Chris Salij가 제안한 솔루션을 수정하여 저에게 도움이되었습니다.
SSLContext ctx = null;
TrustManager[] trustAllCerts = new X509TrustManager[]{new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){return null;}
public void checkClientTrusted(X509Certificate[] certs, String authType){}
public void checkServerTrusted(X509Certificate[] certs, String authType){}
}};
try {
ctx = SSLContext.getInstance("SSL");
ctx.init(null, trustAllCerts, null);
} catch (NoSuchAlgorithmException | KeyManagementException e) {
LOGGER.info("Error loading ssl context {}", e.getMessage());
}
SSLContext.setDefault(ctx);
람다가없는 Jersey 2.x 사용자의 경우 다음을 사용하십시오.
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
public static Client getUnsecureClient() throws Exception
{
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[]{new X509TrustManager()
{
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{}
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}}, new java.security.SecureRandom());
HostnameVerifier allowAll = new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(allowAll).build();
}
JRE 1.7 에서 jersey-client 2.11로 테스트되었습니다 .
가져 오기 오기에 동일한 코드를 추가하기 만하면됩니다. 또한 구현되지 않은 코드도 포함됩니다. 처음에는이 코드에 대해 많은 경쟁 내용을 찾는 데 있습니다. 또한 X509Certificate에 대한 올바른 패키지를 추가합니다. 시행 착오와 함께 작동합니다.
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;
import javax.ws.rs.core.MultivaluedMap;
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
java.security.cert.X509Certificate[] chck = null;
;
return chck;
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] arg0, String arg1)
throws java.security.cert.CertificateException {
// TODO Auto-generated method stub
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] arg0, String arg1)
throws java.security.cert.CertificateException {
// TODO Auto-generated method stub
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
;
}
Jersey 2. *의 경우 :
Client client = ClientBuilder.newBuilder()
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}).build();
-> https://jersey.java.net/documentation/latest/migration.html
Jersey 1.X의 경우
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {}
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {}
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
// or you can return null too
return new java.security.cert.X509Certificate[0];
}
}};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String string, SSLSession sslSession) {
return true;
}
});
풀링 관리자와 함께 Apache http 클라이언트 구성을 사용할 때 허용되는 답변이 작동하지 않는다는 것을 알았습니다.
경우이 ClientConfig.sslContext
및 ClientConfig.hostnameVerifier
세터 자동으로 무시는 되는 것으로 보입니다 . 따라서 아파치 클라이언트 http 클라이언트 구성과 함께 연결 풀링을 사용하는 경우 다음 코드를 사용하여 SSL 확인을 무시할 수 있습니다.
ClientConfig clientConfig = new ClientConfig();
// ... configure your clientConfig
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
}, null);
} catch (NoSuchAlgorithmException e) {
//logger.debug("Ignoring 'NoSuchAlgorithmException' while ignoring ssl certificate validation.");
} catch (KeyManagementException e) {
//logger.debug("Ignoring 'KeyManagementException' while ignoring ssl certificate validation.");
}
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", new SSLConnectionSocketFactory(sslContext, new AbstractVerifier() {
@Override
public void verify(String host, String[] cns, String[] subjectAlts) {
}
}))
.build();
connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
return ClientBuilder.newClient(clientConfig);
좋습니다. 앞으로 Netbackup 서버 (또는 이와 유사한 것)에 연결하고 SSL 인증서를 무시하면서 Java에서 작업을 수행하려는 개발자가 있기 때문에 클래스를 사용할 수 있습니다. 이 나를 위해 일되는 Netbackup 서버에 대한 인증을 위해 Windows Active Directory를 사용합니다.
public static void main(String[] args) throws Exception {
SSLContext sslcontext = null;
try {
sslcontext = SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
try {
sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}}, new java.security.SecureRandom());
} catch (KeyManagementException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
//HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().credentials(username, password).build();
ClientConfig clientConfig = new ClientConfig();
//clientConfig.register(feature);
Client client = ClientBuilder.newBuilder().withConfig(clientConfig)
.sslContext(sslcontext)
.hostnameVerifier((s1, s2) -> true)
.build();
//String the_url = "https://the_server:1556/netbackup/security/cacert";
String the_token;
{
String the_url = "https://the_server:1556/netbackup/login";
WebTarget webTarget = client.target(the_url);
Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
String jsonString = new JSONObject()
.put("domainType", "NT")
.put("domainName", "XX")
.put("userName", "the username")
.put("password", "the password").toString();
System.out.println(jsonString);
Response response = invocationBuilder.post(Entity.json(jsonString));
String data = response.readEntity(String.class);
JSONObject jo = new JSONObject(data);
the_token = jo.getString("token");
System.out.println("token is:" + the_token);
}
{
String the_url = "https://the_server:1556/netbackup/admin/jobs/1122012"; //job id 1122012 is an example
WebTarget webTarget = client.target(the_url);
Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, the_token).header(HttpHeaders.ACCEPT, "application/vnd.netbackup+json;version=1.0");
Response response = invocationBuilder.get();
System.out.println("response status:" + response.getStatus());
String data = response.readEntity(String.class);
//JSONObject jo = new JSONObject(data);
System.out.println(data);
}
}
주제에서 벗어난 것으로 간주 될 수 있다는 것을 알고 있지만 Netbackup 서버에 연결하려는 개발자는 아마 여기서 끝날 것입니다. 그런데이 질문에 대한 모든 답변에 감사드립니다! 내가 말하는 사양은 여기에 있으며 코드 샘플 에는 (현재) Java 예제가 없습니다.
*** 이것은 인증서를 무시하므로 안전하지 않습니다!
이 코드로 나를 위해 일했습니다. Java 1.7 용일 수 있습니다.
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
;
}
참고 URL : https://stackoverflow.com/questions/6047996/ignore-self-signed-ssl-cert-using-jersey-client
'ProgramingTip' 카테고리의 다른 글
Cygwin에서 Windows Python 사용 (0) | 2020.11.29 |
---|---|
제거하는 방법은 무엇입니까? (0) | 2020.11.29 |
PHP var_dump () 값이 값당 한 줄을 표시하도록 만들기 (0) | 2020.11.29 |
혼자 개발자로서 Mercurial을 어떻게 사용합니까? (0) | 2020.11.28 |
자바 프로그래머로서 무엇을 찾아야합니까? (0) | 2020.11.28 |