Improve Jetty integration in order to support consistent HTTP sessions.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / client / SpnegoHttpClient.java
index e5beb69da84371be0acb4656bc9f3a8608c65b55..444f4efb54f3c164813edaedcea5e37d8681caa0 100644 (file)
@@ -1,5 +1,7 @@
 package org.argeo.cms.client;
 
+import java.io.BufferedInputStream;
+import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.http.HttpClient;
@@ -7,9 +9,15 @@ import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
 import java.net.http.HttpResponse.BodyHandler;
 import java.net.http.HttpResponse.BodyHandlers;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.security.KeyManagementException;
 import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.util.Collection;
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
@@ -17,10 +25,13 @@ import javax.net.ssl.X509TrustManager;
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 
+import org.argeo.cms.auth.ConsoleCallbackHandler;
 import org.argeo.cms.auth.RemoteAuthUtils;
 import org.argeo.util.http.HttpHeader;
 
 public class SpnegoHttpClient {
+       public final static String CLIENT_LOGIN_CONTEXT = "CLIENT";
+
        public static void main(String[] args) throws MalformedURLException {
 //             String principal = System.getProperty("javax.security.auth.login.name");
                if (args.length == 0) {
@@ -33,10 +44,10 @@ public class SpnegoHttpClient {
                URL u = new URL(url);
                String server = u.getHost();
 
-               URL jaasUrl = SpnegoHttpClient.class.getResource("jaas.cfg");
+               URL jaasUrl = SpnegoHttpClient.class.getResource("jaas-client-ipa.cfg");
                System.setProperty("java.security.auth.login.config", jaasUrl.toExternalForm());
                try {
-                       LoginContext lc = new LoginContext("SINGLE_USER");
+                       LoginContext lc = new LoginContext(CLIENT_LOGIN_CONTEXT, new ConsoleCallbackHandler());
                        lc.login();
 
                        HttpClient httpClient = openHttpClient(lc.getSubject());
@@ -55,33 +66,47 @@ public class SpnegoHttpClient {
                }
        }
 
-       private static HttpClient openHttpClient(Subject subject) {
+       static HttpClient openHttpClient(Subject subject) {
                HttpClient client = HttpClient.newBuilder() //
-//                             .sslContext(insecureContext()) //
+                               .sslContext(ipaSslContext()) //
                                .version(HttpClient.Version.HTTP_1_1) //
                                .build();
 
                return client;
        }
 
-       static SSLContext insecureContext() {
-               TrustManager[] noopTrustManager = new TrustManager[] { new X509TrustManager() {
-                       public void checkClientTrusted(X509Certificate[] xcs, String string) {
+       @SuppressWarnings("unchecked")
+       static SSLContext ipaSslContext() {
+               try {
+                       final Collection<X509Certificate> certificates;
+                       Path caCertificatePath = Paths.get("/etc/ipa/ca.crt");
+                       if (Files.exists(caCertificatePath)) {
+                               CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
+                               try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(caCertificatePath))) {
+                                       certificates = (Collection<X509Certificate>) certificateFactory.generateCertificates(in);
+                               }
+                       } else {
+                               certificates = null;
                        }
+                       TrustManager[] noopTrustManager = new TrustManager[] { new X509TrustManager() {
+                               public void checkClientTrusted(X509Certificate[] xcs, String string) {
+                               }
 
-                       public void checkServerTrusted(X509Certificate[] xcs, String string) {
-                       }
+                               public void checkServerTrusted(X509Certificate[] xcs, String string) {
+                               }
+
+                               public X509Certificate[] getAcceptedIssuers() {
+                                       if (certificates == null)
+                                               return null;
+                                       return certificates.toArray(new X509Certificate[certificates.size()]);
+                               }
+                       } };
 
-                       public X509Certificate[] getAcceptedIssuers() {
-                               return null;
-                       }
-               } };
-               try {
                        SSLContext sc = SSLContext.getInstance("ssl");
                        sc.init(null, noopTrustManager, null);
                        return sc;
-               } catch (KeyManagementException | NoSuchAlgorithmException e) {
-                       throw new IllegalStateException("Cannot create insecure SSL context ", e);
+               } catch (KeyManagementException | NoSuchAlgorithmException | CertificateException | IOException e) {
+                       throw new IllegalStateException("Cannot create SSL context ", e);
                }
        }