2010-08-08 5 views
10

Ich habe Web-Services basierend auf Jersey erstellt (automatisch über Netbeans generiert).Zugriff auf sichere, erholsame Web-Services mit dem Trikot-Client

Ich habe auch einen Benutzernamen "testClient" mit Passwort "secret" erstellt und Benutzergruppe "Benutzer" erstellt und Datei Realm mit glassfish 3.0.1 admin console verwendet.

Ich habe auch web.xml und sun-web.xml entsprechend zugeordnet.

Meine Webdienste sind erfolgreich gesichert. Wenn ich auf die Website zugreife, erhalte ich eine Sicherheitswarnung und dann werde ich aufgefordert, Benutzernamen und Passwort einzugeben, um auf den Inhalt der Website zugreifen zu können. Es funktioniert gut, wenn über den Webbrowser zugegriffen wird.

Jetzt habe ich einen einfachen Client basierend auf Jersey geschrieben und versucht, auf die Web-Services des 1. Projekts zuzugreifen; der Client-Code ist hier

Auto erzeugt Jersey Client-Code

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; 
    } 

} 

-Code in Main-Methode; automatisch generierten Code

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

Ergebnisse verwendet:

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 

Ich möchte auch mitteilen, dass es sich um zwei verschiedene Projekte auf verschiedenen Servern Glassfish 3.0.1 sind beide aktiv. Ich habe auch versucht, Client und Dienste auf demselben Server auszuführen, aber alles umsonst. Ich stecke fest; Hilf mir bitte.

Prost!

Antwort

16

Ich habe eine gute Ressource zu meinem Problem gefunden. Hier ist es

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

ich einige Änderungen in meinem Code in Bezug auf die gegebenen Quelle gemacht und es funktionierte perfekt. Eigentlich habe ich das Zertifikat und die Schlüsselspeicher nicht richtig übergeben.

Hier ist der vollständige Code.

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); 
     } 
    } 
} 

und Code den Client in Hauptklasse

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(); 
} 
laufen