From 88b7c4965616c6faf0d82bd56df0319e15b876a2 Mon Sep 17 00:00:00 2001 From: nareshpr Date: Thu, 9 Apr 2020 14:50:36 -0700 Subject: [PATCH] HIVE-23173 - User login success/failed attempts should be logged --- .../org/apache/hive/jdbc/HiveConnection.java | 6 ++++-- .../hive/jdbc/HttpRequestInterceptorBase.java | 7 +++++-- jdbc/src/java/org/apache/hive/jdbc/Utils.java | 10 +++++++--- .../hive/service/auth/PlainSaslHelper.java | 7 ++++++- .../service/cli/thrift/ThriftCLIService.java | 9 ++++++--- .../service/cli/thrift/ThriftHttpServlet.java | 16 ++++++++++++++++ 6 files changed, 44 insertions(+), 11 deletions(-) diff --git a/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java b/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java index 7f0d8dcdf4..56f1bd5d63 100644 --- a/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java +++ b/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java @@ -541,13 +541,15 @@ private CloseableHttpClient getHttpClient(Boolean useSsl) throws SQLException { public boolean retryRequest(final HttpResponse response, final int executionCount, final HttpContext context) { int statusCode = response.getStatusLine().getStatusCode(); - boolean ret = statusCode == 401 && executionCount <= 1; + boolean sentCredentials = context.getAttribute(Utils.HIVE_SERVER2_SENT_CREDENTIALS) != null && + context.getAttribute(Utils.HIVE_SERVER2_SENT_CREDENTIALS).equals(Utils.HIVE_SERVER2_CONST_TRUE); + boolean ret = statusCode == 401 && executionCount <= 1 && !sentCredentials; // Set the context attribute to true which will be interpreted by the request // interceptor if (ret) { context.setAttribute(Utils.HIVE_SERVER2_RETRY_KEY, - Utils.HIVE_SERVER2_RETRY_TRUE); + Utils.HIVE_SERVER2_CONST_TRUE); } return ret; } diff --git a/jdbc/src/java/org/apache/hive/jdbc/HttpRequestInterceptorBase.java b/jdbc/src/java/org/apache/hive/jdbc/HttpRequestInterceptorBase.java index bb1abd302d..1e6ddebfeb 100644 --- a/jdbc/src/java/org/apache/hive/jdbc/HttpRequestInterceptorBase.java +++ b/jdbc/src/java/org/apache/hive/jdbc/HttpRequestInterceptorBase.java @@ -70,11 +70,14 @@ public void process(HttpRequest httpRequest, HttpContext httpContext) Utils.needToSendCredentials(cookieStore, cookieName, isSSL)))) || (httpContext.getAttribute(Utils.HIVE_SERVER2_RETRY_KEY) != null && httpContext.getAttribute(Utils.HIVE_SERVER2_RETRY_KEY). - equals(Utils.HIVE_SERVER2_RETRY_TRUE)))) { + equals(Utils.HIVE_SERVER2_CONST_TRUE)))) { addHttpAuthHeader(httpRequest, httpContext); + httpContext.setAttribute(Utils.HIVE_SERVER2_SENT_CREDENTIALS, Utils.HIVE_SERVER2_CONST_TRUE); + } else { + httpContext.setAttribute(Utils.HIVE_SERVER2_SENT_CREDENTIALS, Utils.HIVE_SERVER2_CONST_FALSE); } if (isCookieEnabled) { - httpContext.setAttribute(Utils.HIVE_SERVER2_RETRY_KEY, Utils.HIVE_SERVER2_RETRY_FALSE); + httpContext.setAttribute(Utils.HIVE_SERVER2_RETRY_KEY, Utils.HIVE_SERVER2_CONST_FALSE); } // Insert the additional http headers if (additionalHeaders != null) { diff --git a/jdbc/src/java/org/apache/hive/jdbc/Utils.java b/jdbc/src/java/org/apache/hive/jdbc/Utils.java index 6cb6853077..eb7c0c71bc 100644 --- a/jdbc/src/java/org/apache/hive/jdbc/Utils.java +++ b/jdbc/src/java/org/apache/hive/jdbc/Utils.java @@ -64,10 +64,14 @@ private static final String URI_HIVE_PREFIX = "hive2:"; - // This value is set to true by the setServiceUnavailableRetryStrategy() when the server returns 401 + // This value is set to true by the setServiceUnavailableRetryStrategy() when the server returns 401. + // This value is used only when cookie is sent for authorization. In case the cookie is expired, + // client will send the actual credentials in the next connection request. + // If credentials are sent in the first request it self, then no need to retry. static final String HIVE_SERVER2_RETRY_KEY = "hive.server2.retryserver"; - static final String HIVE_SERVER2_RETRY_TRUE = "true"; - static final String HIVE_SERVER2_RETRY_FALSE = "false"; + static final String HIVE_SERVER2_SENT_CREDENTIALS = "hive.server2.sentCredentials"; + static final String HIVE_SERVER2_CONST_TRUE = "true"; + static final String HIVE_SERVER2_CONST_FALSE = "false"; public static class JdbcConnectionParams { // Note on client side parameter naming convention: diff --git a/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java b/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java index f2ba6bedbc..fd1236413e 100644 --- a/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java +++ b/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java @@ -158,7 +158,12 @@ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallback } PasswdAuthenticationProvider provider = AuthenticationProviderFactory.getAuthenticationProvider(authMethod); - provider.Authenticate(username, password); + try { + provider.Authenticate(username, password); + } catch (Exception e) { + LOG.error("Login attempt is failed for user : " + username + ". Error Messsage : " + e.getMessage()); + throw e; + } if (ac != null) { ac.setAuthorized(true); } diff --git a/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java b/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java index 3938147fef..13cefbe2e6 100644 --- a/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java +++ b/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java @@ -319,8 +319,10 @@ private TStatus unsecureTokenErrorStatus() { public TOpenSessionResp OpenSession(TOpenSessionReq req) throws TException { LOG.info("Client protocol version: " + req.getClient_protocol()); TOpenSessionResp resp = new TOpenSessionResp(); + String userName = null; try { - final SessionHandle sessionHandle = getSessionHandle(req, resp); + userName = getUserName(req); + final SessionHandle sessionHandle = getSessionHandle(req, resp, userName); final int fetchSize = hiveConf.getIntVar(HiveConf.ConfVars.HIVE_SERVER2_THRIFT_RESULTSET_DEFAULT_FETCH_SIZE); @@ -334,7 +336,9 @@ public TOpenSessionResp OpenSession(TOpenSessionReq req) throws TException { if (context != null) { context.setSessionHandle(sessionHandle); } + LOG.info("Login attempt is successful for user : " + userName); } catch (Exception e) { + LOG.error("Login attempt is failed for user : " + userName + ". Error Messsage :" + e.getMessage()); LOG.warn("Error opening session: ", e); resp.setStatus(HiveSQLException.toTStatus(e)); } @@ -462,9 +466,8 @@ private String getShortName(String userName) throws IOException { * @throws LoginException * @throws IOException */ - SessionHandle getSessionHandle(TOpenSessionReq req, TOpenSessionResp res) + SessionHandle getSessionHandle(TOpenSessionReq req, TOpenSessionResp res, String userName) throws HiveSQLException, LoginException, IOException { - String userName = getUserName(req); String ipAddress = getIpAddress(); TProtocolVersion protocol = getMinVersion(CLIService.SERVER_VERSION, req.getClient_protocol()); diff --git a/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java b/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java index 421aa5a4c8..2ccbb618ab 100644 --- a/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java +++ b/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java @@ -253,6 +253,13 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); if(isKerberosAuthMode(authType)) { response.addHeader(HttpAuthUtils.WWW_AUTHENTICATE, HttpAuthUtils.NEGOTIATE); + } else { + try { + LOG.error("Login attempt is failed for user : " + + getUsername(request, authType) + ". Error Messsage :" + e.getMessage()); + } catch (Exception ex) { + // Ignore Exception + } } response.getWriter().println("Authentication Error: " + e.getMessage()); } @@ -511,6 +518,15 @@ public String run() throws HttpAuthenticationException { } } catch (GSSException e) { + if (gssContext != null) { + try { + LOG.error("Login attempt is failed for user : " + + getPrincipalWithoutRealmAndHost(gssContext.getSrcName().toString()) + + ". Error Messsage :" + e.getMessage()); + } catch (Exception ex) { + // Ignore Exception + } + } throw new HttpAuthenticationException("Kerberos authentication failed: ", e); } finally { -- 2.20.1