CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-eclipse-jetty--jetty-server

Core server component of Eclipse Jetty web server providing HTTP server functionality, request handling, and connection management

Pending
Overview
Eval results
Files

security-ssl.mddocs/

Security and SSL

Security and SSL support provides comprehensive HTTPS/TLS encryption, client certificate authentication, security headers, and protocol configuration for secure web applications.

SSL Connection Factory

The SslConnectionFactory enables SSL/TLS encryption for HTTP connections.

public class SslConnectionFactory extends AbstractConnectionFactory 
        implements ConnectionFactory.Detecting, ConnectionFactory.Configuring {
    
    // Constructors
    public SslConnectionFactory();
    public SslConnectionFactory(String nextProtocol);
    public SslConnectionFactory(SslContextFactory.Server sslContextFactory, String nextProtocol);
    
    // SSL Context Factory
    public SslContextFactory.Server getSslContextFactory();
    public void setSslContextFactory(SslContextFactory.Server sslContextFactory);
    
    // Protocol configuration
    public String getNextProtocol();
    public void setNextProtocol(String nextProtocol);
    
    // Buffer configuration
    public boolean isDirectBuffersForEncryption();
    public void setDirectBuffersForEncryption(boolean useDirectBuffers);
    public boolean isDirectBuffersForDecryption();
    public void setDirectBuffersForDecryption(boolean useDirectBuffers);
    
    // Connection creation
    public Connection newConnection(Connector connector, EndPoint endPoint);
    public EndPoint configure(EndPoint endPoint, Connector connector, 
                            ConnectionMetaData connectionMetaData);
}

SslContextFactory.Server

Server-side SSL context factory for configuring SSL/TLS settings.

public class SslContextFactory.Server extends SslContextFactory {
    // Keystore configuration
    public void setKeyStorePath(String keyStorePath);
    public String getKeyStorePath();
    public void setKeyStoreType(String keyStoreType);
    public String getKeyStoreType();
    public void setKeyStorePassword(String keyStorePassword);
    public void setKeyManagerPassword(String keyManagerPassword);
    
    // Truststore configuration
    public void setTrustStorePath(String trustStorePath);
    public String getTrustStorePath();
    public void setTrustStoreType(String trustStoreType);
    public String getTrustStoreType();
    public void setTrustStorePassword(String trustStorePassword);
    
    // Client authentication
    public boolean getWantClientAuth();
    public void setWantClientAuth(boolean wantClientAuth);
    public boolean getNeedClientAuth();
    public void setNeedClientAuth(boolean needClientAuth);
    
    // Protocol configuration
    public String[] getIncludeProtocols();
    public void setIncludeProtocols(String... protocols);
    public String[] getExcludeProtocols();
    public void setExcludeProtocols(String... protocols);
    
    // Cipher suite configuration
    public String[] getIncludeCipherSuites();
    public void setIncludeCipherSuites(String... cipherSuites);
    public String[] getExcludeCipherSuites();
    public void setExcludeCipherSuites(String... cipherSuites);
    
    // SNI configuration
    public boolean isSniRequired();
    public void setSniRequired(boolean sniRequired);
    public String[] getSniHostCheck();
    public void setSniHostCheck(String... hosts);
    
    // Session configuration
    public int getSslSessionCacheSize();
    public void setSslSessionCacheSize(int sslSessionCacheSize);
    public int getSslSessionTimeout();
    public void setSslSessionTimeout(int sslSessionTimeout);
    
    // OCSP configuration
    public boolean isEnableOCSP();
    public void setEnableOCSP(boolean enableOCSP);
    public String getOcspResponderURL();
    public void setOcspResponderURL(String ocspResponderURL);
}

Basic HTTPS Setup

public class BasicHTTPSServer {
    
    public void createHTTPSServer() throws Exception {
        Server server = new Server();
        
        // Create SSL context factory
        SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
        
        // Configure keystore
        sslContextFactory.setKeyStorePath("keystore.jks");
        sslContextFactory.setKeyStorePassword("keystorepassword");
        sslContextFactory.setKeyManagerPassword("keymanagerpassword");
        
        // Create HTTP configuration for HTTPS
        HttpConfiguration httpsConfig = new HttpConfiguration();
        httpsConfig.setSecureScheme("https");
        httpsConfig.setSecurePort(8443);
        httpsConfig.addCustomizer(new SecureRequestCustomizer());
        
        // Create HTTPS connector
        ServerConnector httpsConnector = new ServerConnector(server,
            new SslConnectionFactory(sslContextFactory, "http/1.1"),
            new HttpConnectionFactory(httpsConfig));
        httpsConnector.setPort(8443);
        
        server.addConnector(httpsConnector);
        
        // Set handler
        server.setHandler(new SimpleHandler());
        
        server.start();
        server.join();
    }
}

Advanced SSL Configuration

public class AdvancedSSLConfiguration {
    
    public SslContextFactory.Server createSecureSSLContextFactory() {
        SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
        
        // Keystore configuration
        sslContextFactory.setKeyStorePath("conf/keystore.jks");
        sslContextFactory.setKeyStorePassword("keystorepassword");
        sslContextFactory.setKeyManagerPassword("keypassword");
        sslContextFactory.setKeyStoreType("JKS");
        
        // Truststore for client certificates
        sslContextFactory.setTrustStorePath("conf/truststore.jks");
        sslContextFactory.setTrustStorePassword("truststorepassword");
        sslContextFactory.setTrustStoreType("JKS");
        
        // Client certificate authentication
        sslContextFactory.setWantClientAuth(true);   // Request client cert
        sslContextFactory.setNeedClientAuth(false);  // Don't require it
        
        // Protocol configuration - only modern TLS versions
        sslContextFactory.setIncludeProtocols("TLSv1.2", "TLSv1.3");
        sslContextFactory.setExcludeProtocols(
            "SSL", "SSLv2", "SSLv3", "TLSv1", "TLSv1.1"
        );
        
        // Secure cipher suites only
        sslContextFactory.setIncludeCipherSuites(
            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
            "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
            "TLS_AES_256_GCM_SHA384",
            "TLS_CHACHA20_POLY1305_SHA256",
            "TLS_AES_128_GCM_SHA256"
        );
        
        // Exclude weak cipher suites
        sslContextFactory.setExcludeCipherSuites(
            ".*NULL.*", ".*RC4.*", ".*MD5.*", ".*DES.*", ".*DSS.*"
        );
        
        // SNI configuration
        sslContextFactory.setSniRequired(false);
        sslContextFactory.setSniHostCheck("example.com", "*.example.com");
        
        // Session configuration
        sslContextFactory.setSslSessionCacheSize(1000);
        sslContextFactory.setSslSessionTimeout(3600); // 1 hour
        
        // OCSP stapling
        sslContextFactory.setEnableOCSP(true);
        
        // Additional security settings
        sslContextFactory.setRenegotiationAllowed(false);
        
        return sslContextFactory;
    }
    
    public void setupHTTPSWithClientAuth(Server server) {
        SslContextFactory.Server sslContextFactory = createSecureSSLContextFactory();
        
        // Require client certificates
        sslContextFactory.setNeedClientAuth(true);
        
        // HTTP configuration with secure customizer
        HttpConfiguration httpsConfig = new HttpConfiguration();
        httpsConfig.setSecureScheme("https");
        httpsConfig.setSecurePort(8443);
        
        SecureRequestCustomizer secureCustomizer = new SecureRequestCustomizer();
        secureCustomizer.setStsMaxAge(31536000);         // 1 year HSTS
        secureCustomizer.setStsIncludeSubDomains(true);  // Include subdomains
        httpsConfig.addCustomizer(secureCustomizer);
        
        // Create HTTPS connector
        ServerConnector httpsConnector = new ServerConnector(server,
            new SslConnectionFactory(sslContextFactory, "http/1.1"),
            new HttpConnectionFactory(httpsConfig));
        httpsConnector.setPort(8443);
        
        server.addConnector(httpsConnector);
    }
}

SecureRequestCustomizer

Customizer that adds security features to HTTPS requests.

public class SecureRequestCustomizer implements HttpConfiguration.Customizer {
    // HSTS (HTTP Strict Transport Security) configuration
    public long getStsMaxAge();
    public void setStsMaxAge(long stsMaxAge);
    public boolean isStsIncludeSubDomains();
    public void setStsIncludeSubDomains(boolean stsIncludeSubDomains);
    
    // SNI (Server Name Indication) configuration
    public boolean isSniRequired();
    public void setSniRequired(boolean sniRequired);
    public boolean isSniHostCheck();
    public void setSniHostCheck(boolean sniHostCheck);
    
    // Request customization
    public Request customize(Request request, HttpConfiguration configuration);
}

Security Headers

Custom Security Headers Handler

public class SecurityHeadersHandler extends Handler.Wrapper {
    private final Map<String, String> securityHeaders;
    
    public SecurityHeadersHandler() {
        this.securityHeaders = new HashMap<>();
        
        // Default security headers
        securityHeaders.put("X-Content-Type-Options", "nosniff");
        securityHeaders.put("X-Frame-Options", "DENY");
        securityHeaders.put("X-XSS-Protection", "1; mode=block");
        securityHeaders.put("Referrer-Policy", "strict-origin-when-cross-origin");
        securityHeaders.put("Content-Security-Policy", 
            "default-src 'self'; script-src 'self' 'unsafe-inline'; " +
            "style-src 'self' 'unsafe-inline'; img-src 'self' data:");
        securityHeaders.put("Permissions-Policy", 
            "geolocation=(), microphone=(), camera=()");
    }
    
    public void setSecurityHeader(String name, String value) {
        securityHeaders.put(name, value);
    }
    
    public void removeSecurityHeader(String name) {
        securityHeaders.remove(name);
    }
    
    @Override
    public boolean handle(Request request, Response response, Callback callback) 
            throws Exception {
        
        // Add security headers to response
        for (Map.Entry<String, String> header : securityHeaders.entrySet()) {
            response.getHeaders().put(header.getKey(), header.getValue());
        }
        
        return super.handle(request, response, callback);
    }
}

HSTS Handler

public class HSTSHandler extends Handler.Wrapper {
    private final long maxAge;
    private final boolean includeSubDomains;
    private final boolean preload;
    
    public HSTSHandler(long maxAge, boolean includeSubDomains, boolean preload) {
        this.maxAge = maxAge;
        this.includeSubDomains = includeSubDomains;
        this.preload = preload;
    }
    
    @Override
    public boolean handle(Request request, Response response, Callback callback) 
            throws Exception {
        
        // Only add HSTS header for HTTPS requests
        if (request.getConnectionMetaData().isSecure()) {
            StringBuilder hsts = new StringBuilder();
            hsts.append("max-age=").append(maxAge);
            
            if (includeSubDomains) {
                hsts.append("; includeSubDomains");
            }
            
            if (preload) {
                hsts.append("; preload");
            }
            
            response.getHeaders().put("Strict-Transport-Security", hsts.toString());
        }
        
        return super.handle(request, response, callback);
    }
}

Client Certificate Authentication

public class ClientCertificateHandler extends Handler.Abstract {
    
    @Override
    public boolean handle(Request request, Response response, Callback callback) 
            throws Exception {
        
        // Check if connection is secure
        if (!request.getConnectionMetaData().isSecure()) {
            sendError(response, callback, 403, "HTTPS required");
            return true;
        }
        
        // Get client certificates
        X509Certificate[] clientCerts = request.getConnectionMetaData().getPeerCertificates();
        
        if (clientCerts == null || clientCerts.length == 0) {
            sendError(response, callback, 401, "Client certificate required");
            return true;
        }
        
        // Validate client certificate
        X509Certificate clientCert = clientCerts[0];
        if (!isValidClientCertificate(clientCert)) {
            sendError(response, callback, 403, "Invalid client certificate");
            return true;
        }
        
        // Extract user information from certificate
        String userDN = clientCert.getSubjectX500Principal().getName();
        String commonName = extractCommonName(userDN);
        
        // Set authenticated user in request
        request.setAttribute("authenticatedUser", commonName);
        request.setAttribute("clientCertificate", clientCert);
        
        // Generate success response
        response.setStatus(200);
        response.getHeaders().put("Content-Type", "application/json");
        
        String json = String.format(
            "{\"authenticated\": true, \"user\": \"%s\", \"subject\": \"%s\"}", 
            commonName, userDN);
        
        response.write(true, ByteBuffer.wrap(json.getBytes()), callback);
        return true;
    }
    
    private boolean isValidClientCertificate(X509Certificate cert) {
        try {
            // Check certificate validity period
            cert.checkValidity();
            
            // Check certificate issuer (example)
            String issuer = cert.getIssuerX500Principal().getName();
            if (!issuer.contains("CN=My CA")) {
                return false;
            }
            
            // Additional validation logic...
            
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    private String extractCommonName(String dn) {
        // Extract CN from distinguished name
        String[] parts = dn.split(",");
        for (String part : parts) {
            String trimmed = part.trim();
            if (trimmed.startsWith("CN=")) {
                return trimmed.substring(3);
            }
        }
        return "Unknown";
    }
    
    private void sendError(Response response, Callback callback, int status, String message) {
        response.setStatus(status);
        response.getHeaders().put("Content-Type", "text/plain");
        response.write(true, ByteBuffer.wrap(message.getBytes()), callback);
    }
}

HTTPS Redirect Handler

public class HTTPSRedirectHandler extends Handler.Abstract {
    private final int httpsPort;
    
    public HTTPSRedirectHandler(int httpsPort) {
        this.httpsPort = httpsPort;
    }
    
    @Override
    public boolean handle(Request request, Response response, Callback callback) 
            throws Exception {
        
        // Check if request is already HTTPS
        if (request.getConnectionMetaData().isSecure()) {
            return false; // Let next handler process
        }
        
        // Build HTTPS URL
        String scheme = "https";
        String host = request.getHeaders().get("Host");
        if (host == null) {
            host = "localhost";
        }
        
        // Remove port from host if present
        if (host.contains(":")) {
            host = host.substring(0, host.indexOf(":"));
        }
        
        String httpsUrl = scheme + "://" + host + 
            (httpsPort != 443 ? ":" + httpsPort : "") + 
            request.getHttpURI().getPathQuery();
        
        // Send redirect response
        response.setStatus(301); // Permanent redirect
        response.getHeaders().put("Location", httpsUrl);
        response.getHeaders().put("Connection", "close");
        
        callback.succeeded();
        return true;
    }
}

Complete Secure Server Setup

public class SecureServerSetup {
    
    public Server createSecureServer() throws Exception {
        Server server = new Server();
        
        // HTTP connector (redirects to HTTPS)
        ServerConnector httpConnector = new ServerConnector(server);
        httpConnector.setPort(8080);
        server.addConnector(httpConnector);
        
        // HTTPS connector
        SslContextFactory.Server sslContextFactory = createSslContextFactory();
        HttpConfiguration httpsConfig = createHttpsConfiguration();
        
        ServerConnector httpsConnector = new ServerConnector(server,
            new SslConnectionFactory(sslContextFactory, "http/1.1"),
            new HttpConnectionFactory(httpsConfig));
        httpsConnector.setPort(8443);
        server.addConnector(httpsConnector);
        
        // Create handler chain with security
        Handler securityChain = createSecurityHandlerChain();
        server.setHandler(securityChain);
        
        return server;
    }
    
    private SslContextFactory.Server createSslContextFactory() {
        SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
        
        // SSL configuration
        sslContextFactory.setKeyStorePath("conf/keystore.jks");
        sslContextFactory.setKeyStorePassword("password");
        sslContextFactory.setTrustStorePath("conf/truststore.jks");
        sslContextFactory.setTrustStorePassword("password");
        
        // Security settings
        sslContextFactory.setIncludeProtocols("TLSv1.2", "TLSv1.3");
        sslContextFactory.setExcludeProtocols("SSLv3", "TLSv1", "TLSv1.1");
        sslContextFactory.setIncludeCipherSuites(
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
        );
        
        // Client certificate support
        sslContextFactory.setWantClientAuth(true);
        
        return sslContextFactory;
    }
    
    private HttpConfiguration createHttpsConfiguration() {
        HttpConfiguration httpsConfig = new HttpConfiguration();
        httpsConfig.setSecureScheme("https");
        httpsConfig.setSecurePort(8443);
        
        // Add secure request customizer
        SecureRequestCustomizer secureCustomizer = new SecureRequestCustomizer();
        secureCustomizer.setStsMaxAge(31536000);       // 1 year HSTS
        secureCustomizer.setStsIncludeSubDomains(true); // Include subdomains
        httpsConfig.addCustomizer(secureCustomizer);
        
        return httpsConfig;
    }
    
    private Handler createSecurityHandlerChain() {
        // HTTPS redirect handler
        HTTPSRedirectHandler httpsRedirect = new HTTPSRedirectHandler(8443);
        
        // Security headers handler
        SecurityHeadersHandler securityHeaders = new SecurityHeadersHandler();
        
        // HSTS handler
        HSTSHandler hstsHandler = new HSTSHandler(31536000, true, false);
        
        // Client certificate authentication (optional)
        ClientCertificateHandler clientCertAuth = new ClientCertificateHandler();
        
        // Application handler
        Handler applicationHandler = new MyApplicationHandler();
        
        // Chain handlers together
        httpsRedirect.setHandler(securityHeaders);
        securityHeaders.setHandler(hstsHandler);
        hstsHandler.setHandler(clientCertAuth);
        clientCertAuth.setHandler(applicationHandler);
        
        return httpsRedirect;
    }
}

SSL Debugging and Monitoring

public class SSLMonitoringHandler extends Handler.Wrapper {
    
    @Override
    public boolean handle(Request request, Response response, Callback callback) 
            throws Exception {
        
        ConnectionMetaData connMeta = request.getConnectionMetaData();
        
        if (connMeta.isSecure()) {
            logSSLInfo(request);
        }
        
        return super.handle(request, response, callback);
    }
    
    private void logSSLInfo(Request request) {
        ConnectionMetaData connMeta = request.getConnectionMetaData();
        
        System.out.println("SSL Connection Info:");
        System.out.println("  Protocol: " + connMeta.getProtocol());
        System.out.println("  Secure: " + connMeta.isSecure());
        
        // Client certificate info
        X509Certificate[] clientCerts = connMeta.getPeerCertificates();
        if (clientCerts != null && clientCerts.length > 0) {
            X509Certificate clientCert = clientCerts[0];
            System.out.println("  Client Certificate:");
            System.out.println("    Subject: " + clientCert.getSubjectX500Principal().getName());
            System.out.println("    Issuer: " + clientCert.getIssuerX500Principal().getName());
            System.out.println("    Serial: " + clientCert.getSerialNumber());
        } else {
            System.out.println("  No client certificate");
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-eclipse-jetty--jetty-server

docs

configuration.md

connection-management.md

context-resources.md

handlers.md

index.md

request-logging.md

request-response.md

security-ssl.md

server-core.md

session-management.md

utility-handlers.md

tile.json