Search code examples
javaresthttpsjersey

Serve https with Jersey 1


I'm trying to update an old RESTful API to allow it to serve https; I don't actually need the added security but I've got clients complaining about mixed context - this is on a deployed desktop application that is just using REST to communicate; not a deployed web app.

This is a jersey 1 implementation and I'm trying to avoid having to upgrade to Jersey 2. The HTTP serving was very easy:

this.server = HttpServerFactory.create(baseUri, 
                new DefaultResourceConfig(DataPaqResource.class));

So I've looked around and pulled from the javadocs the following to start https or http based on the base uri passed in:

StartWebServer(String baseUri) throws IOException, NoSuchAlgorithmException{
    ResourceListeners.addDataPaqResourceListener(this);

    if (baseUri.startsWith("https")) {
        SSLContext sslContext = SSLContext.getInstance ("SSL");
        this.server = (HttpsServer) HttpServerFactory.create(baseUri, 
            new DefaultResourceConfig(DataPaqResource.class));
        ((HttpsServer) this.server).setHttpsConfigurator (new HttpsConfigurator(sslContext) {
            public void configure (HttpsParameters params) {
                SSLContext c = getSSLContext();

                // get the default parameters
                SSLParameters sslparams = c.getDefaultSSLParameters();
                 
                params.setSSLParameters(sslparams);
            }
        });
    }else {
        this.server = HttpServerFactory.create(baseUri, 
            new DefaultResourceConfig(DataPaqResource.class));
    }
    System.out.println("Started web server on " + baseUri + " imp " + 
        this.server.getClass().getName());
}

This works fine for http but with https I get:

Error: Client network socket disconnected before secure TLS connection was established

This error is from postman but obviously browsers fail too. Basically I know that the https is configured incorrectly but I'm not sure how to configure it. I don't need the security; I just need to be able to serve https with the minimal amount of configuration.

Any and all help gratefully received!


Solution

  • Solved it - it was basically all working except I loaded the keystore wrong!

    //keystore generated with
    //keytool -genkeypair -keyalg RSA -alias self_signed -keypass datapaq -keystore 
    //datapaq.keystore -storepass datapaq
    public class StartWebServer implements DataPaqResourceListener{
    
    private HttpServer server;
    private static final String password = "datapaq";
    
    StartWebServer(String baseUri) throws IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException{
        ResourceListeners.addDataPaqResourceListener(this);
        if (baseUri.startsWith("https")) {
            
            this.server = (HttpsServer) HttpServerFactory.create(baseUri, 
                    new DefaultResourceConfig(DataPaqResource.class));
            SSLContext sslContext = SSLContext.getInstance ("SSL");
    
            KeyStore ks = getKeyStore();
    
            // Set up the key manager factory
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(ks, password.toCharArray());
            
            // Set up the trust manager factory
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(ks);
            
            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
            
            // Set up the HTTPS context and parameters
            ((HttpsServer) this.server).setHttpsConfigurator (new HttpsConfigurator(sslContext) {
                 public void configure (HttpsParameters params) {
                     try {
                            // Initialise the SSL context
                            SSLContext context = getSSLContext();
                            SSLEngine engine = context.createSSLEngine();
                            engine.setNeedClientAuth(false);
                            engine.setWantClientAuth(false);
                            params.setNeedClientAuth(false);
                            params.setWantClientAuth(false);
                            params.setCipherSuites(engine.getEnabledCipherSuites());
                            params.setProtocols(engine.getEnabledProtocols());
    
                           // Set the SSL parameters
                            SSLParameters sslParameters = context.getSupportedSSLParameters();
                            params.setSSLParameters(sslParameters);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                 }
             });
        }else {
            this.server = HttpServerFactory.create(baseUri, 
                    new DefaultResourceConfig(DataPaqResource.class));
        }
    }
    
    private KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException {
        // Initialise the keystore
        char[] password = "datapaq".toCharArray();
        KeyStore ks = KeyStore.getInstance("JKS");
        InputStream fis = new FileInputStream("datapaq.keystore");
        ks.load(fis, password);
        return ks;
    
    }
    }