2010-08-08 10 views
10

He creado servicios web basados ​​en Jersey (generados automáticamente a través de Netbeans).Acceder a servicios web seguros y seguros utilizando el cliente jersey

También he creado un nombre de usuario "testClient" con contraseña "secreta" y he creado el grupo de usuarios "Usuarios" y utilicé el archivo Realm usando la consola de administración glassfish 3.0.1.

También he mapeado web.xml y sun-web.xml en consecuencia.

Mis servicios web están asegurados con éxito; cuando accedo al sitio web, recibo una advertencia de seguridad y luego le pido un nombre de usuario y una contraseña para acceder a cualquier contenido del sitio web. Está funcionando bien cuando se accede a través del navegador web.

Ahora he escrito un cliente simple basado en jersey e intenté acceder a los servicios web ofrecidos por el primer proyecto; el código de cliente está aquí

auto generada código de cliente Jersey

public class JerseyClient { 
    private WebResource webResource; 
    private Client client; 
    private static final String BASE_URI = "https://localhost:9028/testsecurity2/resources"; 

    public JerseyClient() { 
     com.sun.jersey.api.client.config.ClientConfig config = new com.sun.jersey.api.client.config.DefaultClientConfig(); // SSL configuration 
     // SSL configuration 
     config.getProperties().put(com.sun.jersey.client.urlconnection.HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new com.sun.jersey.client.urlconnection.HTTPSProperties(getHostnameVerifier(), getSSLContext())); 
     client = Client.create(config); 
     webResource = client.resource(BASE_URI).path("manufacturers"); 
    } 

    public <T> T get_XML(Class<T> responseType) throws UniformInterfaceException { 
     return webResource.accept(javax.ws.rs.core.MediaType.APPLICATION_XML).get(responseType); 
    } 

    public <T> T get_JSON(Class<T> responseType) throws UniformInterfaceException { 
     return webResource.accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType); 
    } 

    public void close() { 
     client.destroy(); 
    } 

    public void setUsernamePassword(String username, String password) { 
     client.addFilter(new com.sun.jersey.api.client.filter.HTTPBasicAuthFilter(username, password)); 
    } 

    private HostnameVerifier getHostnameVerifier() { 
     return new HostnameVerifier() { 

      @Override 
      public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) { 
       return true; 
      } 
     }; 
    } 

    private SSLContext getSSLContext() { 
     javax.net.ssl.TrustManager x509 = new javax.net.ssl.X509TrustManager() { 

      @Override 
      public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws java.security.cert.CertificateException { 
       return; 
      } 

      @Override 
      public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws java.security.cert.CertificateException { 
       return; 
      } 

      @Override 
      public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
       return null; 
      } 
     }; 
     SSLContext ctx = null; 
     try { 
      ctx = SSLContext.getInstance("SSL"); 
      ctx.init(null, new javax.net.ssl.TrustManager[]{x509}, null); 
     } catch (java.security.GeneralSecurityException ex) { 
     } 
     return ctx; 
    } 

} 

Código en el método principal; utiliza código generado automáticamente

JerseyClient client = new JerseyClient(); 
client.setUsernamePassword("testClient", "secret"); 
Object response = client.get_XML(String.class); 
// do whatever with response 
client.close(); 

Resultados:

Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake 
     at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:128) 
     at com.sun.jersey.api.client.filter.HTTPBasicAuthFilter.handle(HTTPBasicAuthFilter.java:78) 
     at com.sun.jersey.api.client.Client.handle(Client.java:457) 
     at com.sun.jersey.api.client.WebResource.handle(WebResource.java:557) 
     at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69) 
     at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:451) 
     at clients.JerseyClient.get_XML(JerseyClient.java:23) 
     at clients.NewMain1.main(NewMain1.java:20) 
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake 
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:808) 
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112) 
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1139) 
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123) 
     at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) 
     at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) 
     at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1049) 
     at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:373) 
     at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318) 
     at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:215) 
     at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:126) 
     ... 7 more 
Caused by: java.io.EOFException: SSL peer shut down incorrectly 
     at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333) 
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:789) 
     ... 17 more 
Java Result: 1 

También quiero informar que se trata de dos proyectos diferentes que se ejecutan en diferentes servidores tanto son GlassFish 3.0.1. También intenté ejecutar el cliente y los servicios en el mismo servidor, pero todo fue en vano. Estoy atascado; amablemente ayúdame

¡Salud!

Respuesta

16

he encontrado un buen recurso con respecto a mi problema. Aquí es

http://wiki.open-esb.java.net/attach/RestBCEchoSSL/SslClient.java

Hice algunos cambios en mi código con respecto a la fuente dada y funcionó perfectamente. En realidad, no estaba pasando el certificado y las tiendas de claves correctamente.

Aquí está el código completo.

package clients; 

import com.sun.jersey.api.client.*; 
import javax.net.ssl.*; 
import java.io.*; 
import java.net.Socket; 
import java.security.*; 
import javax.ws.rs.core.UriBuilder; 
import com.sun.jersey.client.urlconnection.HTTPSProperties; 

public class JerseyClient { 

    private WebResource webResource; 
    private Client client; 
    //private static final String BASE_URI = "https://localhost:9028/testsecurity2/resources"; 
    private static final String truststore_path = "D:/Practice Apps/glassfish-3.0.1 Stand Alone/glassfish/domains/domain2/config/cacerts.jks"; 
    private static final String truststore_password = "changeit"; 
    private static final String keystore_path = "D:/Practice Apps/glassfish-3.0.1 Stand Alone/glassfish/domains/domain2/config/keystore.jks"; 
    private static final String keystore_password = "changeit"; 
    private static final String url = "https://localhost:9029/testsecurity2/resources/manufacturers/"; 

    public JerseyClient() { 
     com.sun.jersey.api.client.config.ClientConfig config = new com.sun.jersey.api.client.config.DefaultClientConfig(); // SSL configuration 
     // SSL configuration 
     config.getProperties().put(com.sun.jersey.client.urlconnection.HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new com.sun.jersey.client.urlconnection.HTTPSProperties(getHostnameVerifier(), getSSLContext())); 
     client = Client.create(config); 
     webResource = client.resource(url); 
    } 

    public <T> T get_XML(Class<T> responseType) throws UniformInterfaceException { 
     return webResource.accept(javax.ws.rs.core.MediaType.APPLICATION_XML).get(responseType); 
    } 

    public <T> T get_JSON(Class<T> responseType) throws UniformInterfaceException { 
     return webResource.accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType); 
    } 

    public void close() { 
     client.destroy(); 
    } 

    public void setUsernamePassword(String username, String password) { 
     client.addFilter(new com.sun.jersey.api.client.filter.HTTPBasicAuthFilter(username, password)); 
    } 

    private HostnameVerifier getHostnameVerifier() { 
     return new HostnameVerifier() { 

      @Override 
      public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) { 
       return true; 
      } 
     }; 
    } 

    private SSLContext getSSLContext() { 

     TrustManager mytm[] = null; 
     KeyManager mykm[] = null; 

     try { 
      mytm = new TrustManager[]{new MyX509TrustManager(truststore_path, truststore_password.toCharArray())}; 
      mykm = new KeyManager[]{new MyX509KeyManager(keystore_path, keystore_password.toCharArray())}; 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 

     SSLContext ctx = null; 
     try { 
      ctx = SSLContext.getInstance("SSL"); 
      ctx.init(mykm, mytm, null); 
     } catch (java.security.GeneralSecurityException ex) { 
     } 
     return ctx; 
    } 

    /** 
    * Taken from http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html 
    * 
    */ 
    static class MyX509TrustManager implements X509TrustManager { 

     /* 
     * The default PKIX X509TrustManager9. We'll delegate 
     * decisions to it, and fall back to the logic in this class if the 
     * default X509TrustManager doesn't trust it. 
     */ 
     X509TrustManager pkixTrustManager; 

     MyX509TrustManager(String trustStore, char[] password) throws Exception { 
      this(new File(trustStore), password); 
     } 

     MyX509TrustManager(File trustStore, char[] password) throws Exception { 
      // create a "default" JSSE X509TrustManager. 

      KeyStore ks = KeyStore.getInstance("JKS"); 

      ks.load(new FileInputStream(trustStore), password); 

      TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX"); 
      tmf.init(ks); 

      TrustManager tms[] = tmf.getTrustManagers(); 

      /* 
      * Iterate over the returned trustmanagers, look 
      * for an instance of X509TrustManager. If found, 
      * use that as our "default" trust manager. 
      */ 
      for (int i = 0; i < tms.length; i++) { 
       if (tms[i] instanceof X509TrustManager) { 
        pkixTrustManager = (X509TrustManager) tms[i]; 
        return; 
       } 
      } 

      /* 
      * Find some other way to initialize, or else we have to fail the 
      * constructor. 
      */ 
      throw new Exception("Couldn't initialize"); 
     } 

     /* 
     * Delegate to the default trust manager. 
     */ 
     public void checkClientTrusted(X509Certificate[] chain, String authType) 
       throws CertificateException { 
      try { 
       pkixTrustManager.checkClientTrusted(chain, authType); 
      } catch (CertificateException excep) { 
       // do any special handling here, or rethrow exception. 
      } 
     } 

     /* 
     * Delegate to the default trust manager. 
     */ 
     public void checkServerTrusted(X509Certificate[] chain, String authType) 
       throws CertificateException { 
      try { 
       pkixTrustManager.checkServerTrusted(chain, authType); 
      } catch (CertificateException excep) { 
       /* 
       * Possibly pop up a dialog box asking whether to trust the 
       * cert chain. 
       */ 
      } 
     } 

     /* 
     * Merely pass this through. 
     */ 
     public X509Certificate[] getAcceptedIssuers() { 
      return pkixTrustManager.getAcceptedIssuers(); 
     } 
    } 

    /** 
    * Inspired from http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html 
    * 
    */ 
    static class MyX509KeyManager implements X509KeyManager { 

     /* 
     * The default PKIX X509KeyManager. We'll delegate 
     * decisions to it, and fall back to the logic in this class if the 
     * default X509KeyManager doesn't trust it. 
     */ 
     X509KeyManager pkixKeyManager; 

     MyX509KeyManager(String keyStore, char[] password) throws Exception { 
      this(new File(keyStore), password); 
     } 

     MyX509KeyManager(File keyStore, char[] password) throws Exception { 
      // create a "default" JSSE X509KeyManager. 

      KeyStore ks = KeyStore.getInstance("JKS"); 
      ks.load(new FileInputStream(keyStore), password); 

      KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509", "SunJSSE"); 
      kmf.init(ks, password); 

      KeyManager kms[] = kmf.getKeyManagers(); 

      /* 
      * Iterate over the returned keymanagers, look 
      * for an instance of X509KeyManager. If found, 
      * use that as our "default" key manager. 
      */ 
      for (int i = 0; i < kms.length; i++) { 
       if (kms[i] instanceof X509KeyManager) { 
        pkixKeyManager = (X509KeyManager) kms[i]; 
        return; 
       } 
      } 

      /* 
      * Find some other way to initialize, or else we have to fail the 
      * constructor. 
      */ 
      throw new Exception("Couldn't initialize"); 
     } 

     public PrivateKey getPrivateKey(String arg0) { 
      return pkixKeyManager.getPrivateKey(arg0); 
     } 

     public X509Certificate[] getCertificateChain(String arg0) { 
      return pkixKeyManager.getCertificateChain(arg0); 
     } 

     public String[] getClientAliases(String arg0, Principal[] arg1) { 
      return pkixKeyManager.getClientAliases(arg0, arg1); 
     } 

     public String chooseClientAlias(String[] arg0, Principal[] arg1, Socket arg2) { 
      return pkixKeyManager.chooseClientAlias(arg0, arg1, arg2); 
     } 

     public String[] getServerAliases(String arg0, Principal[] arg1) { 
      return pkixKeyManager.getServerAliases(arg0, arg1); 
     } 

     public String chooseServerAlias(String arg0, Principal[] arg1, Socket arg2) { 
      return pkixKeyManager.chooseServerAlias(arg0, arg1, arg2); 
     } 
    } 
} 

y el código para ejecutar el cliente en la clase principal

public static void main(String[] args) { 

    JerseyClient client = new JerseyClient(); 
    client.setUsernamePassword("testClient", "secret"); 
    Object response = client.get_XML(String.class); 
    System.out.println(response); 
    // do whatever with response 
    client.close(); 
} 
Cuestiones relacionadas