xiaoqiao 3 месяцев назад
Родитель
Сommit
ef1b55dcac

+ 171 - 28
src/main/java/com/bowintek/practice/config/ElasticsearchConfig.java

@@ -8,28 +8,37 @@ import co.elastic.clients.transport.ElasticsearchTransport;
 import co.elastic.clients.transport.rest_client.RestClientTransport;
 import co.elastic.clients.util.ContentType;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.http.Header;
-import org.apache.http.HttpHeaders;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.*;
+import org.apache.http.auth.AuthSchemeProvider;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.config.Lookup;
+import org.apache.http.config.RegistryBuilder;
 import org.apache.http.conn.ssl.NoopHostnameVerifier;
 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.impl.auth.SPNegoSchemeFactory;
 import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.message.BasicHeader;
 import org.apache.http.ssl.SSLContextBuilder;
-import org.elasticsearch.client.RestClient;
-import org.elasticsearch.client.RestClientBuilder;
+import org.elasticsearch.client.*;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 import javax.annotation.Resource;
+import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -40,17 +49,28 @@ public class ElasticsearchConfig {
 
     @Resource
     EsConfig config;
+    private static final BasicCredentialsProvider CREDENTIALS_PROVIDER = new BasicCredentialsProvider();
+    private static final HostnameVerifier HOSTNAME_VERIFIER = new NoopHostnameVerifier();
+    //private static final Lookup<AuthSchemeProvider> AUTH_SCHEME_REGISTRY = RegistryBuilder.create().register("Negotiate", new SPNegoSchemeFactory(true)).build();
+    private static final SSLContext SSL_CONTEXT;
 
+    static {
+        TrustStrategy trustStrategy = new TrustStrategy() {
+            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+                return true;
+            }
+        };
 
+        try {
+            SSL_CONTEXT = (new SSLContextBuilder()).loadTrustMaterial((KeyStore)null, trustStrategy).build();
+        } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException var2) {
+            GeneralSecurityException e = var2;
+            log.error("Init ssl context failed.", e);
+            throw new RuntimeException(e);
+        }
+    }
     @Bean
     public ElasticsearchClient esClient() {
-        SSLContext sslContext;
-        /*try {
-            sslContext =new SSLContextBuilder().loadTrustMaterial(null, TrustSelfSignedStrategy.INSTANCE)
-                    .build();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }*/
         //System.setProperty("java.security.krb5.conf",config.getKrb5());
         //System.setProperty("java.security.auth.login.config", config.getJaas());
         //System.setProperty("java.security.auth.login.defaultConfigurationName", "EsClient");
@@ -65,28 +85,51 @@ public class ElasticsearchConfig {
                 ).build();*/
 
         this.setSecConfig();
-        RestClient restClient = RestClient.builder(new HttpHost(config.getHosts(),config.getPort(),config.getSchema()))
-                .setHttpClientConfigCallback(httpClientBuilder->
-                        httpClientBuilder.setDefaultHeaders(List.of(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())))
-                ).build();
-        SmRestClientBuilder builder=  new SmRestClientBuilder(restClient.getNodes());
+        RestClient restClient = RestClient.builder(new HttpHost(config.getHosts(), config.getPort(), config.getSchema()))
+                .setHttpClientConfigCallback(httpClientBuilder -> {
+                    httpClientBuilder.setSSLContext(SSL_CONTEXT);
+                    //httpClientBuilder.setDefaultAuthSchemeRegistry(AUTH_SCHEME_REGISTRY);
+                    httpClientBuilder.setDefaultCredentialsProvider(CREDENTIALS_PROVIDER);
+                    httpClientBuilder.setSSLHostnameVerifier(HOSTNAME_VERIFIER);
+                    httpClientBuilder.setDefaultHeaders(List.of(new BasicHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON), new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)));
+
+                    return httpClientBuilder;
+                }).build();
+        SmRestClientBuilder builder = new SmRestClientBuilder(restClient.getNodes());
         builder.setSslEnabled(true);
-        builder.setEsJaasConfFile(config.getJaas());
+        builder.setEsJaasConfFile(LoginUtil.getEsJaasConfPath());
         builder.authenticate(restClient);
-        //RestClient restClient = RestClient.builder(new HttpHost(config.getHosts(),config.getPort(),config.getSchema())).build();
+
+        Request request = new Request("GET", "/test4/_search");
+        Cancellable cancellable = restClient.performRequestAsync(
+                request,
+                new ResponseListener() {
+                    @Override
+                    public void onSuccess(Response response) {
+                        log.info("onSuccess:" + response.toString());
+                    }
+
+                    @Override
+                    public void onFailure(Exception exception) {
+                        log.info("onFailure:" + exception.getMessage());
+                    }
+                }
+        );
+
         ElasticsearchTransport transport = new RestClientTransport(
                 restClient, new JacksonJsonpMapper());
+
         ElasticsearchClient client = new ElasticsearchClient(transport);
 
-        //restClient.getHttpClient().
         try {
             // 查看指定索引
+            log.info("name:"+client.info().name());
+            log.info("version:"+client.info().version());
             GetIndexResponse getIndexResponse = client.indices().get(s -> s.index("test4"));
             Map<String, IndexState> result = getIndexResponse.result();
             result.forEach((k, v) -> log.info("key = {},value = {}", k, v));
-        }catch (Exception ex){
-            log.info(ex.getMessage());
-            ex.printStackTrace();
+        } catch (Exception ex) {
+            log.info("查看指定索引:" + ex.getMessage());
         }
         return client;
     }
@@ -94,7 +137,8 @@ public class ElasticsearchConfig {
     private void setSecConfig() {
         try {
             String userKeytabFile = config.getKeytab();
-            LoginUtil.setJaasFile(config.getUser(), userKeytabFile, config.getJaas());
+            String principal = this.principalHandler(config.getUser(), new HttpHost(config.getHosts(), config.getPort(), config.getSchema()).toHostString());
+            LoginUtil.setJaasFile(principal, userKeytabFile, null);
             LoginUtil.setKrb5Config(config.getKrb5());
             System.setProperty("elasticsearch.kerberos.jaas.appname", "EsClient");
             System.setProperty("es.security.indication", "true");
@@ -105,6 +149,105 @@ public class ElasticsearchConfig {
         }
 
     }
+
+    private String principalHandler(String principal, String hostAndPort) {
+        if (principal != null && !principal.isEmpty()) {
+            if (principal.contains("@")) {
+                return principal;
+            } else {
+                String scheme = "https://";
+                String realm = this.getRealm(hostAndPort, scheme);
+                if (realm != null && !realm.isEmpty()) {
+                    return principal + "@" + realm;
+                } else {
+                    log.info("The server realm is null.");
+                    return principal;
+                }
+            }
+        } else {
+            log.warn("The principal is null because the properties is not set principal.");
+            return null;
+        }
+    }
+
+    private String getRealm(String hostAndPorts, String scheme) {
+
+        String[] hostAndPortArray = hostAndPorts.split(",");
+        String[] var4 = hostAndPortArray;
+        int var5 = hostAndPortArray.length;
+
+        for (int var6 = 0; var6 < var5; ++var6) {
+            String hostAndPort = var4[var6];
+            String serverRealm = this.getServerRealm(hostAndPort, scheme);
+            if (serverRealm != null && !serverRealm.isEmpty()) {
+                if (serverRealm.toLowerCase(Locale.ENGLISH).startsWith("elasticsearch/hadoop.")) {
+                    return serverRealm.substring(serverRealm.indexOf("@") + 1);
+                }
+
+                return serverRealm;
+            }
+        }
+
+        log.error("No available services, server realm is null.");
+        return null;
+    }
+
+    private String getServerRealm(String hostAndPort, String scheme) {
+        String serverRealm = null;
+        InputStream is = null;
+        ByteArrayOutputStream os = null;
+
+        try {
+            HttpClientBuilder builder = HttpClientBuilder.create();
+            builder.setSSLHostnameVerifier(HOSTNAME_VERIFIER);
+            builder.setSSLContext(SSL_CONTEXT);
+            HttpClient client = builder.build();
+            HttpGet httpGet = new HttpGet(scheme + hostAndPort + "/elasticsearch/serverrealm");
+            HttpResponse response = client.execute(httpGet);
+            int httpStatus = response.getStatusLine().getStatusCode();
+            if (200 == httpStatus) {
+                is = response.getEntity().getContent();
+                os = new ByteArrayOutputStream();
+                byte[] buffer = new byte[64];
+
+                int size;
+                while (-1 != (size = is.read(buffer))) {
+                    os.write(buffer, 0, size);
+                }
+
+                serverRealm = os.toString(StandardCharsets.UTF_8.displayName());
+                log.info("Success to get the service realm " + serverRealm + ".");
+            } else {
+                log.error("Cannot get server realm at " + hostAndPort + ".");
+            }
+        } catch (Exception var25) {
+            Exception e = var25;
+            log.error("Get server realm failed.", e);
+        } finally {
+            IOException e;
+            if (os != null) {
+                try {
+                    os.close();
+                } catch (IOException var24) {
+                    e = var24;
+                    log.error("Close http response byte array output stream error.", e);
+                }
+            }
+
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException var23) {
+                    e = var23;
+                    log.error("Close http response input stream failed.", e);
+                }
+            }
+
+        }
+
+        return serverRealm;
+    }
+
     private static CredentialsProvider getCredentialsProvider(String username, String password) {
         CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
         credentialsProvider.setCredentials(AuthScope.ANY,

+ 0 - 1
src/main/java/com/bowintek/practice/config/EsConfig.java

@@ -15,7 +15,6 @@ public class EsConfig {
     private String user;
     private String password;
     private String krb5;
-    private String jaas;
     private String keytab;
     private int port;
     private String schema;

+ 3 - 2
src/main/java/com/bowintek/practice/config/LoginUtil.java

@@ -36,6 +36,7 @@ public class LoginUtil {
             if (krb5ConfFile != null && !krb5ConfFile.isEmpty()) {
                 System.setProperty("java.security.krb5.conf", krb5ConfFile);
                 ret = System.getProperty("java.security.krb5.conf");
+                log.info(String.format(Locale.ENGLISH, "krb5ConfFile is %s.", krb5ConfFile));
             }
 
             if (ret == null || ret.isEmpty() || !ret.equals(krb5ConfFile)) {
@@ -73,8 +74,8 @@ public class LoginUtil {
         if (!writeFlag) {
             System.setProperty("java.security.auth.login.config", jaasPath);
             writeFlag = true;
-            log.debug(String.format(Locale.ENGLISH, "jaasPath is %s.", jaasPath));
-            log.debug(String.format(Locale.ENGLISH, "keytabPath is %s.", keytabPath));
+            log.info(String.format(Locale.ENGLISH, "jaasPath is %s.", jaasPath));
+            log.info(String.format(Locale.ENGLISH, "keytabPath is %s.", keytabPath));
         }
 
         esJaasConfPath = jaasPath;

+ 12 - 2
src/main/java/com/bowintek/practice/config/SmRestClientBuilder.java

@@ -217,7 +217,7 @@ public final class SmRestClientBuilder {
             login.invoke(krb5LoginModule);
             commit.invoke(krb5LoginModule);
             subj = loginSubject;
-            LOG.info("Get kerberos TGT successfully.");
+            LOG.info("Get kerberos TGT successfully.loginSubject:"+loginSubject.toString());
         } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException | ClassNotFoundException var8) {
             ReflectiveOperationException e = var8;
             LOG.error("Get kerberos TGT failed." + e);
@@ -257,7 +257,7 @@ public final class SmRestClientBuilder {
     private static AppConfigurationEntry[] readAppConfigurationEntryByAppName(String appName) {
         LOG.info(String.format(Locale.ENGLISH, "Try to read the jaas configuration entry again, app name is %s.", appName));
         AppConfigurationEntry[] entries = null;
-        LOG.info("Read application configuration entry from Es jaas conf file.");
+        LOG.info("Read application configuration entry from Es jaas conf file.esJaasConfFile:"+esJaasConfFile);
         if (esJaasConfFile != null && !esJaasConfFile.isEmpty()) {
             entries = readAppConfigurationEntryFromFile(esJaasConfFile, appName);
             LOG.info(String.format(Locale.ENGLISH, " Complete to read from Es jaas conf file, app name is %s.", appName));
@@ -558,7 +558,17 @@ public final class SmRestClientBuilder {
         return realm;
     }
 
+    private void wrapSecureHttpAsyncClientBuilder(HttpAsyncClientBuilder httpClientBuilder) {
+        if (this.customSSLContext != null) {
+            httpClientBuilder.setSSLContext(this.customSSLContext);
+        } else {
+            httpClientBuilder.setSSLContext(SSL_CONTEXT);
+        }
 
+       // httpClientBuilder.setDefaultAuthSchemeRegistry(AUTH_SCHEME_REGISTRY);
+        httpClientBuilder.setDefaultCredentialsProvider(CREDENTIALS_PROVIDER);
+        httpClientBuilder.setSSLHostnameVerifier(HOSTNAME_VERIFIER);
+    }
 
     static {
         CREDENTIALS_PROVIDER.setCredentials(AuthScope.ANY, new Credentials() {