문제

I am having a problem here since ytday in fact. I am trying to load a jar file dynamically at runtime over https url - and i can't figure out how to exactly do it. I am able to load the jar over standard http: url but not when using https:

public void addURL(URL https) throws IOException {
    HttpsURLConnection conn = (HttpsURLConnection) https.openConnection();


    Class<?>[] parameters = new Class[]{URL.class}; 
    log.info("https url : " + https);


    // IMPORTANT: MUST use the webapp classloader - so derived extension classes car esolve their base classes
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();        
    // cast to a URL class loader so we can additional JAR(s) to the search path
    URLClassLoader webappClassLoader = (URLClassLoader)contextClassLoader;  
    Class<?> sysclass = URLClassLoader.class;

    Method method;
    try {
        method = sysclass.getDeclaredMethod("addURL", parameters);
        method.setAccessible(true);
        method.invoke(webappClassLoader, new Object[]{ https });
    } catch (NoSuchMethodException | SecurityException e) {
        e.printStackTrace();
    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        e.printStackTrace();
    }
}

Help much appreciated :) in pointing / showing me where or what to add etc.

도움이 되었습니까?

해결책

Since you are dealing with Secure Connections, you are stepping into the area of Certificates.

Java thinks that your Server is not trusted. You could understand that from the stack traces.

You have two choices here. You can let your program to ignore the Certificate Validation. You will need to execute this code only once before you call addURL.

import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.*;

private TrustManager[] getBypassingTrustManager()
{
    TrustManager[] certs = new TrustManager[]
        {
            new X509TrustManager()
            {
                public X509Certificate[] getAcceptedIssuers()
                {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] certs, String t)
                {
                }

                public void checkServerTrusted(X509Certificate[] certs, String t)
                {
                }
            }
        };
    return certs;
}


SSLContext sslCtx = SSLContext.getInstance("SSL");
TrustManager trustManager[] = getBypassingTrustManager();
sslCtx.init(null, trustManager, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx.getSocketFactory());

The above approach is not great in the sense of Security. Far better if you learn how Java Keystores work (java.security.KeyStore). Instead of ignoring Certificate Validation, you can keep the Certificate from your Server in a Keystore file. Your application can then load your keystore, which makes Java trusting your Servers.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top