stoty commented on code in PR #5881: URL: https://github.com/apache/hbase/pull/5881#discussion_r1601547952
########## hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/Client.java: ########## @@ -377,19 +476,59 @@ public HttpResponse execute(Cluster cluster, HttpUriRequest method, Header[] hea * @param uri the String to parse as a URL. * @throws IOException if unknown protocol is found. */ - private void negotiate(HttpUriRequest method, String uri) throws IOException { + private void negotiate(HttpUriRequest method, String uri) + throws IOException, GeneralSecurityException { try { AuthenticatedURL.Token token = new AuthenticatedURL.Token(); - KerberosAuthenticator authenticator = new KerberosAuthenticator(); - authenticator.authenticate(new URL(uri), token); - // Inject the obtained negotiated token in the method cookie - injectToken(method, token); + if (authenticator == null) { + authenticator = new KerberosAuthenticator(); + if (trustStore.isPresent()) { + // The authenticator does not use Apache HttpClient, so we need to + // configure it separately to use the specified trustStore + Configuration sslConf = setupTrustStoreForHadoop(trustStore.get()); + SSLFactory sslFactory = new SSLFactory(Mode.CLIENT, sslConf); + sslFactory.init(); + authenticator.setConnectionConfigurator(sslFactory); + } + } + URL url = new URL(uri); + authenticator.authenticate(url, token); + if (sticky) { + BasicClientCookie authCookie = new BasicClientCookie("hadoop.auth", token.toString()); + // Hadoop eats the domain even if set by server + authCookie.setDomain(url.getHost()); + stickyContext.getCookieStore().addCookie(authCookie); + } else { + // session cookie is NOT set for backwards compatibility for non-sticky mode + // Inject the obtained negotiated token in the method cookie + // This is only done for this single request, the next one will trigger a new SPENGO + // handshake + injectToken(method, token); + } } catch (AuthenticationException e) { LOG.error("Failed to negotiate with the server.", e); throw new IOException(e); } } + private Configuration setupTrustStoreForHadoop(KeyStore trustStore) + throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException { + String tmpdir = + Files.createTempDirectory("hbase_rest_client_truststore").toFile().getAbsolutePath(); + String trustStoreLocation = tmpdir + File.separator + "truststore.jks"; Review Comment: Done ########## hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/Client.java: ########## @@ -176,22 +229,56 @@ public Client(Cluster cluster, Configuration conf, boolean sslEnabled) { */ public Client(Cluster cluster, String trustStorePath, Optional<String> trustStorePassword, Optional<String> trustStoreType) { - this(cluster, HBaseConfiguration.create(), trustStorePath, trustStorePassword, trustStoreType); + this(cluster, HBaseConfiguration.create(), true, trustStorePath, trustStorePassword, + trustStoreType); } /** - * Constructor, allowing to define custom trust store (only for SSL connections) + * Constructor that accepts an optional trustStore and authentication information for either BASIC + * or BEARER authentication in sticky mode, which does not use the old faulty load balancing + * logic, and enables correct session handling. If neither userName/password, nor the bearer token + * is specified, the client falls back to SPNEGO auth. The loadTrustsore static method can be used + * to load a local trustStore file. This is the preferred constructor to use. + * @param cluster the cluster definition + * @param conf HBase/Hadoop configuration + * @param sslEnabled use HTTPS + * @param trustStore the optional trustStore object + * @param userName for BASIC auth + * @param password for BASIC auth + * @param bearerToken for BEAERER auth + */ + public Client(Cluster cluster, Configuration conf, boolean sslEnabled, + Optional<KeyStore> trustStore, Optional<String> userName, Optional<String> password, + Optional<String> bearerToken) { + initialize(cluster, conf, sslEnabled, true, trustStore, userName, password, bearerToken); + } + + /** + * Constructor, allowing to define custom trust store (only for SSL connections) This constructor + * also enables sticky mode. This is a preferred constructor when not using BASIC or JWT + * authentication. Clients created by this will not use the old faulty load balancing logic. * @param cluster the cluster definition - * @param conf Configuration + * @param conf HBase/Hadoop Configuration * @param trustStorePath custom trust store to use for SSL connections * @param trustStorePassword password to use for custom trust store * @param trustStoreType type of custom trust store * @throws ClientTrustStoreInitializationException if the trust store file can not be loaded */ - public Client(Cluster cluster, Configuration conf, String trustStorePath, + public Client(Cluster cluster, Configuration conf, boolean sslEnabled, String trustStorePath, Review Comment: Done -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@hbase.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org