Search code examples
sslservletsjettymutual-authentication

How to use jetty to set up 2 way SSL Authentication Connection


I want to create a servlet using 2 way ssl connector. I created test2wayssl.jks and initiated SslSelectChannelConnector When i send request from postman with client certificate, the response in postman is

There was an error connecting to 127.0.0.1:29226/2wayssl.

Here is my code below. But it does not work.

Server server = new Server(29226);

SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("2-way-ssl-authentication/test2wayssl.jks");
sslContextFactory.setKeyStorePassword("123456"); 
sslContextFactory.setKeyManagerPassword("123456");
sslContextFactory.setTrustAll(true);

SslSelectChannelConnector sslConnector = new SslSelectChannelConnector(sslContextFactory);
sslConnector.setAllowRenegotiate(true); 
sslConnector.setHost("localhost");
sslConnector.setServer(server);      

server.addConnector(sslConnector);

ServletHandler handler = new ServletHandler();
handler.addServletWithMapping(HelloServlet.class, "/2wayssl");
server.setHandler(handler); 

try { 
  server.start(); 
} catch (Exception e) {
  e.printStackTrace();  // TODO impl
}

Below is my servlet class

  @SuppressWarnings("serial")
  public static class HelloServlet extends HttpServlet 
  {
    @Override
    protected void doPost(HttpServletRequest request,
                         HttpServletResponse response) throws IOException
    {
      response.setStatus(HttpServletResponse.SC_OK);
      response.setContentType("text/html");
      response.setCharacterEncoding("utf-8");
      response.getWriter().println("<h1>2 Way SSL Authentication</h1>");
    }
  }

Any help is appreciated.


Solution

  • SslSelectChannelConnector is from Jetty 8 and older which are now EOL/End of Life, and does not support client certificates, upgrade to supported and stable version of Jetty first.

    How this is done with Jetty 9.4.27.v20200227 is by using the SslContextFactory.Server and one (or both) of the options

    Example:

    Server server = new Server();
    int httpsPort = 8443;
    
    // Setup HTTP Connector
    HttpConfiguration httpConf = new HttpConfiguration();
    httpConf.setSecurePort(httpsPort);
    httpConf.setSecureScheme("https");
    
    // Setup SSL
    SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
    sslContextFactory.setKeyStoreResource(findKeyStorePath());
    sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
    sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
    sslContextFactory.setWantClientAuth(true); // Option 1
    sslContextFactory.setNeedClientAuth(true); // Option 2
    
    // Setup HTTPS Configuration
    HttpConfiguration httpsConf = new HttpConfiguration();
    httpsConf.setSecureScheme("https");
    httpsConf.setSecurePort(httpsPort);
    httpsConf.addCustomizer(new SecureRequestCustomizer()); // adds ssl info to request object
    
    // Establish the HTTPS ServerConnector
    ServerConnector httpsConnector = new ServerConnector(server,
        new SslConnectionFactory(sslContextFactory,"http/1.1"),
        new HttpConnectionFactory(httpsConf));
    httpsConnector.setPort(httpsPort);
    
    server.addConnector(httpsConnector);
    
    // Add a Handlers for requests
    HandlerList handlers = new HandlerList();
    handlers.addHandler(new SecuredRedirectHandler());
    handlers.addHandler(new HelloHandler("Hello Secure World"));
    server.setHandler(handlers);
    
    server.start();
    server.join();