Pregunta

¿Necesita alguna orientación.

Tengo aplicación Java WebStart y quiero que se conecte a un servidor a través de SSL.just añadiendo una propiedad como: System.setProperty ( "javax.net.ssl.trustStore", "my.keystore"); Pero ya que una programa JAWS se descarga desde el servidor no funcionaba y no tienen un my.keystore en el sistema de archivos local. Así que decidió distribuir el certificado a todos clients.I hizo lo siguiente y funcionó.

  1. Lea este almacén de confianza como (método getResourceAsStream uso) corriente.
  2. Guardar en cualquier archivo en la máquina cliente (sometemp)
  3. Call System.setProperty ( "javax.net.ssl.trustStore", trustStorePath);

Pero estoy seguro de que hay mejores soluciones que esta .. ¿Alguna idea para que sea mejor?

public boolean validateUserFromActiveDirectory(String userId) {
                    final String MEMBER_GROUP = "CN=asdadasd,OU=asdasdasd Accounts,OU=adasdas,OU=asdasdas,DC=asdasdas,DC=asdasdas,DC=adasdasd,DC=asdasdasd";
            String employeeNumber = "";
            final String LDAP_INIT_CTX = "com.sun.jndi.ldap.LdapCtxFactory";
            final String LDAP_URL = "ldap://xx-ssssssss.eee.eee.eeeee.eeeee:636";
            final String MY_ATTRS[] = { "employeeNumber" };
            String adminPassword = "somepassword";
            String securityProtocol = "ssl";
            boolean isValidUser = false;
            try {

                  Hashtable env = new Hashtable();
                  env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_INIT_CTX);
                  env.put(Context.PROVIDER_URL, LDAP_URL);
                  env.put(Context.SECURITY_AUTHENTICATION, "simple");
                  env.put(Context.REFERRAL, "follow");
                  env.put(Context.SECURITY_PRINCIPAL, MEMBER_GROUP);
                  env.put(Context.SECURITY_CREDENTIALS, adminPassword);
                  env.put(Context.SECURITY_PROTOCOL, securityProtocol);

            //C:\Documents and Settings\yourusername\Local Settings\Temp
            File tf = File.createTempFile("someTruststore", ".jks");
            tf.deleteOnExit();
            byte buffer[] = new byte[0x1000];
               ClassLoader cl = JNDI.class.getClassLoader();
            InputStream in = cl.getResourceAsStream(
                    "someTruststore.jks");
            FileOutputStream out = new FileOutputStream(tf);
            int cnt;
            while ((cnt = in.read(buffer)) != -1)
                out.write(buffer, 0, cnt);
            in.close();
            out.close();
            System.setProperty("javax.net.ssl.trustStore", tf
                            .getAbsolutePath());

                  DirContext context = new InitialLdapContext(env, null);
                  SearchControls searchControls = new SearchControls();
                  searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                  NamingEnumeration results = context.search(
                              "XX=ent,XX=abc,XX=aaaaa,XX=aaaa", "(sAMAccountName="
                                          + userId + ")", searchControls);

                  if (results != null && results.hasMore()) {
                      //some logic

                        }
                  }
            } catch (Exception e) {
                  e.printStackTrace();
            }
            return isValidUser;
      }

-Padur =========================== ** =============

/**

*  * /

package util;

/**
 * @author spaduri
 *
 */
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

public class CustomSSLSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory factory;

    public CustomSSLSocketFactory() {
        try {
            SSLContext sslcontext = null;
              // Call getKeyManagers to get suitable key managers
            KeyManager[] kms=getKeyManagers();
            if (sslcontext == null) {
                sslcontext = SSLContext.getInstance("SSL");
                sslcontext.init(kms,
                new TrustManager[] { new CustomTrustManager() },
                new java.security.SecureRandom());
            }
            factory = (SSLSocketFactory) sslcontext.getSocketFactory();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    public static SocketFactory getDefault() {
        return new CustomSSLSocketFactory();
    }

    public Socket createSocket(Socket socket, String s, int i, boolean flag) throws IOException {
        return factory.createSocket(socket, s, i, flag);
    }

    public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr1, int j) throws IOException {
        return factory.createSocket(inaddr, i, inaddr1, j);
    }

    public Socket createSocket(InetAddress inaddr, int i) throws IOException {
        return factory.createSocket(inaddr, i);
    }

    public Socket createSocket(String s, int i, InetAddress inaddr, int j) throws IOException {
        return factory.createSocket(s, i, inaddr, j);
    }

    public Socket createSocket(String s, int i) throws IOException {
        return factory.createSocket(s, i);
    }

    public String[] getDefaultCipherSuites() {
        return factory.getSupportedCipherSuites();
    }

    public String[] getSupportedCipherSuites() {
        return factory.getSupportedCipherSuites();
    }

 protected KeyManager[] getKeyManagers()
        throws IOException, GeneralSecurityException
      {
        // First, get the default KeyManagerFactory.
        String alg=KeyManagerFactory.getDefaultAlgorithm();
        KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg);

        // Next, set up the KeyStore to use. We need to load the file into
        // a KeyStore instance.

        ClassLoader cl = CustomSSLSocketFactory.class.getClassLoader();
        // read the file someTrustStore from the jar file from a classpath
        InputStream in = cl.getResourceAsStream("ssl/someTruststore.jks");
        //FileInputStream fis=new FileInputStream(adentTruststore.jks);
        KeyStore ks=KeyStore.getInstance("jks");
        ks.load(in, null);
        in.close();

        // Now we initialise the KeyManagerFactory with this KeyStore
        kmFact.init(ks, null);

        // And now get the KeyManagers
        KeyManager[] kms=kmFact.getKeyManagers();
        return kms;
      }
}

package util;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class CustomTrustManager implements X509TrustManager {

    public void checkClientTrusted(X509Certificate[] cert, String authType) {
        return;
    }

    public void checkServerTrusted(X509Certificate[] cert, String authType) {
        return;
    }

    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}

Laz apreciar su paciencia, tratando de aprender cuando consigo algún tiempo. Empecé a escribir mi propia CustomSSLSocketFactory..right ahora estoy pasando por alto la seguridad ... basado en el ejemplo de platino solutions.If yo que ... se la pase la información como un texto claro en la red?

Ahora me pregunto ¿qué debería hacer con el archivo de almacén de confianza que estoy teniendo "sometruststore.jks" archivo. ¿Qué debo hacer con ese ..Do tengo wrie mi propio software TrustManager personalizada? Por favor, me guía en la dirección correcta.

-padur

¿Fue útil?

Solución

podría hacerlo sin tener que depender de las propiedades del sistema y el sistema de archivos. Al leer el almacén de claves como una corriente como que está haciendo y la creación de su propia SSLSocketFactory sería mucho más limpio.

import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

...

    // assume keyStore is the KeyStore you read via getResourceAsStream
    final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
    trustManagerFactory.init(keyStore);

    final SSLContext context = SSLContext.getInstance("SSL");
    context.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

    final URL url = new URL("https://whatever");
    final HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
    urlConnection.setSSLSocketFactory(context.getSocketFactory());

...

No he verificado, pero no veo ninguna razón por qué esto no debería trabajo a través de Webstart.

Actualizado:

Usted menciona que usted está buscando para conectar con el directorio activo, así que supongo que se va a utilizar LDAPS como el protocolo? Si es así, tal vez el código en este URL lata servir de inspiración? Vas a tener que crear una subclase de javax.net.ssl.SSLSocketFactory (ver BlindSSLSocketFactoryTest en que platinumsolutions Link) que envuelve la lógica anterior de crear las SSLContext los delegados y las llamadas a la SSLSocketFactory que context.getSocketFactory() crea.

public class TrustedSSLSocketFactory extends SSLSocketFactory {
    private static SSLContext context;
    public static void initTrustedSSLSocketFactory(final KeyStore keyStore) throws Exception {
        final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
        trustManagerFactory.init(keyStore);

        final SSLContext context = SSLContext.getInstance("SSL");
        context.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
    }

    public static SocketFactory getDefault() {
        return context.getSocketFactory();
    }

    public Socket createSocket(String arg0, int arg1) throws IOException, UnknownHostException {
        return trustedFactory.createSocket(arg0, arg1);
    }

    public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
        return trustedFactory.createSocket(arg0, arg1);
    }

    public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3) throws IOException, UnknownHostException {
        return trustedFactory.createSocket(arg0, arg1, arg2, arg3);
    }

    public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException {
        return trustedFactory.createSocket(arg0, arg1, arg2, arg3);
    }
}

Con suerte que recopila, soy incapaz de probarlo en el momento! También tenga en cuenta la pereza con la cláusula throws en initTrustedSSLSocketFactory.

A continuación, cuando se configura el entorno LDAP, el uso

TrustedSSLSocketFactory.initTrustedSSLSocketFactory(keyStore);
env.put("java.naming.ldap.factory.socket", TrustedSSLSocketFactory.class.getName())

de una manera similar al código de muestra a platinumsolutions. Espero que esto es más de lo que está buscando?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top