最后,有几个问题。-由Gradle设置了奇怪的合格JDK导致的API权限问题-相同的JDK问题导致了SSLparams的问题-我最初的示例未设置信任库。
有趣的是,我最终更改为wantClientAuth(true),并在处理程序中进行了身份验证。
package authserv;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;import java.net.InetSocketAddress;import java.security.KeyStore;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLParameters;import javax.net.ssl.SSLSession;import javax.net.ssl.TrustManagerFactory;import com.sun.net.httpserver.HttpExchange;import com.sun.net.httpserver.HttpHandler;import com.sun.net.httpserver.HttpsConfigurator;import com.sun.net.httpserver.HttpsExchange;import com.sun.net.httpserver.HttpsParameters;import com.sun.net.httpserver.HttpsServer;public class AuthServer { final static String SERVER_PWD = "aaaaaa"; final static String KST_SERVER = "keys/server.jks"; final static String TST_SERVER = "keys/servertrust.jks"; public static HttpsServer server; public static void main(String[] args) throws Exception { server = makeServer(); server.start(); System.out.println("Server running, hit enter to stop.n"); System.in.read(); //AuthClient cl = new AuthClient(); cl.testIt(); server.stop(0); } public static HttpsServer makeServer() throws Exception { server = HttpsServer.create(new InetSocketAddress(8888), 0); //server.setHttpsConfigurator(new HttpsConfigurator(SSLContext.getInstance("TLS"))); // Default config with no auth requirement. SSLContext sslCon = createSSLContext(); MyConfigger authconf = new MyConfigger(sslCon); server.setHttpsConfigurator(authconf); server.createContext("/auth", new HelloHandler()); return server; } private static SSLContext createSSLContext() { SSLContext sslContext = null; KeyStore ks; KeyStore ts; try{ sslContext = SSLContext.getInstance("TLS"); ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(KST_SERVER), SERVER_PWD.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, SERVER_PWD.toCharArray()); ts = KeyStore.getInstance("JKS"); ts.load(new FileInputStream(TST_SERVER), SERVER_PWD.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ts); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); } catch (Exception e) { e.printStackTrace(); } return sslContext; }}class MyConfigger extends HttpsConfigurator { public MyConfigger(SSLContext sslContext) { super(sslContext); } @Override public void configure(HttpsParameters params) { SSLContext sslContext = getSSLContext(); SSLParameters sslParams = sslContext.getDefaultSSLParameters(); sslParams.setNeedClientAuth(true); params.setNeedClientAuth(true); params.setSSLParameters(sslParams); }}class HelloHandler implements HttpHandler { public void handle(HttpExchange t) throws IOException { HttpsExchange ts = (HttpsExchange) t; SSLSession sess = ts.getSSLSession(); //if( sess.getPeerPrincipal() != null) System.out.println(sess.getPeerPrincipal().toString()); // Principal never populated. System.out.printf("Responding to host: %sn",sess.getPeerHost()); t.getResponseHeaders().set("Content-Type", "text/plain"); t.sendResponseHeaders(200,0); String response = "Hello! You seem trustworthy!n"; OutputStream os = t.getResponseBody(); os.write(response.getBytes()); os.close(); }}这是一个向客户展示失败和成功的客户:
package authserv;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.InputStreamReader;import java.net.SocketException;import java.net.URL;import java.security.KeyStore;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.KeyManager;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLHandshakeException;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManagerFactory;public class AuthClient{ static String NO_KEYSTORE = ""; static String UNAUTH_KEYSTORE = "keys/unauthclient.jks"; // Doesn't exist in server trust store, should fail authentication. static String AUTH_KEYSTORE = "keys/authclient.jks"; // Exists in server trust store, should pass authentication. static String TRUSTSTORE = "keys/clienttrust.jks"; static String CLIENT_PWD = "aaaaaa"; public static void main(String[] args) throws Exception { AuthClient cl = new AuthClient(); System.out.println("No keystore:"); cl.testIt(NO_KEYSTORE); System.out.println("Unauth keystore:"); cl.testIt(UNAUTH_KEYSTORE); System.out.println("Auth keystore:"); cl.testIt(AUTH_KEYSTORE); } public void testIt(String jksFile){ try { String https_url = "https://localhost:8888/auth/"; URL url; url = new URL(https_url); HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); conn.setSSLSocketFactory(getSSLFactory(jksFile)); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setUseCaches(false); // Print response BufferedReader bir = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = null; while((line = bir.readLine()) != null) { System.out.println(line); } bir.close(); conn.disconnect(); } catch (SSLHandshakeException|SocketException e) { System.out.println(e.getMessage()); System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } private static SSLSocketFactory getSSLFactory(String jksFile) throws Exception { // Create key store KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); KeyManager[] kmfs = null; if( jksFile.length() > 0 ) { keyStore.load(new FileInputStream(jksFile), CLIENT_PWD.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm()); kmf.init(keyStore, CLIENT_PWD.toCharArray()); kmfs = kmf.getKeyManagers(); } // create trust store (validates the self-signed server!) KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(new FileInputStream(TRUSTSTORE), CLIENT_PWD.toCharArray()); TrustManagerFactory trustFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); trustFactory.init(trustStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmfs, trustFactory.getTrustManagers(), null); return sslContext.getSocketFactory(); }}


