in thriftserver/server/src/main/scala/org/apache/livy/thriftserver/cli/ThriftHttpServlet.scala [78:174]
override protected def doPost(
request: HttpServletRequest, response: HttpServletResponse): Unit = {
var clientUserName: String = null
var requireNewCookie: Boolean = false
try {
if (xsrfFilterEnabled) {
val continueProcessing = ThriftHttpServlet.doXsrfFilter(request, response)
if (!continueProcessing) {
warn("Request did not have valid XSRF header, rejecting.")
return
}
}
// If the cookie based authentication is already enabled, parse the
// request and validate the request cookies.
if (isCookieAuthEnabled) {
clientUserName = validateCookie(request)
requireNewCookie = clientUserName == null
if (requireNewCookie) {
info("Could not validate cookie sent, will try to generate a new cookie")
}
}
// If the cookie based authentication is not enabled or the request does
// not have a valid cookie, use the kerberos or password based authentication
// depending on the server setup.
if (clientUserName == null) {
// For a kerberos setup
if (ThriftHttpServlet.isKerberosAuthMode(authType)) {
val delegationToken = request.getHeader(ThriftHttpServlet.HIVE_DELEGATION_TOKEN_HEADER)
// Each http request must have an Authorization header
if ((delegationToken != null) && (!delegationToken.isEmpty)) {
clientUserName = doTokenAuth(request, response)
} else {
clientUserName = doKerberosAuth(request)
}
} else {
// For password based authentication
clientUserName = doPasswdAuth(request, authType)
}
}
debug(s"Client username: $clientUserName")
// Set the thread local username to be used for doAs if true
SessionInfo.setUserName(clientUserName)
// find proxy user if any from query param
val doAsQueryParam = ThriftHttpServlet.getDoAsQueryParam(request.getQueryString)
if (doAsQueryParam != null) {
SessionInfo.setProxyUserName(doAsQueryParam)
}
val clientIpAddress = request.getRemoteAddr
debug("Client IP Address: " + clientIpAddress)
// Set the thread local ip address
SessionInfo.setIpAddress(clientIpAddress)
// get forwarded hosts address
val forwardedFor = request.getHeader(ThriftHttpServlet.X_FORWARDED_FOR)
if (forwardedFor != null) {
debug(s"${ThriftHttpServlet.X_FORWARDED_FOR}:$forwardedFor")
SessionInfo.setForwardedAddresses(forwardedFor.split(",").toList.asJava)
} else {
SessionInfo.setForwardedAddresses(List.empty.asJava)
}
// Generate new cookie and add it to the response
if (requireNewCookie && !authType.equalsIgnoreCase(AuthTypes.NOSASL.toString)) {
val cookieToken = HttpAuthUtils.createCookieToken(clientUserName)
val hs2Cookie = createCookie(signer.signCookie(cookieToken))
if (isHttpOnlyCookie) {
response.setHeader("SET-COOKIE", ThriftHttpServlet.getHttpOnlyCookieHeader(hs2Cookie))
} else {
response.addCookie(hs2Cookie)
}
info("Cookie added for clientUserName " + clientUserName)
}
super.doPost(request, response);
} catch {
case e: HttpAuthenticationException =>
error("Error: ", e)
// Send a 401 to the client
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED)
if(ThriftHttpServlet.isKerberosAuthMode(authType)) {
response.addHeader(HttpAuthUtils.WWW_AUTHENTICATE, HttpAuthUtils.NEGOTIATE)
}
// scalastyle:off println
response.getWriter.println("Authentication Error: " + e.getMessage)
// scalastyle:on println
} finally {
// Clear the thread locals
SessionInfo.clearUserName()
SessionInfo.clearIpAddress()
SessionInfo.clearProxyUserName()
SessionInfo.clearForwardedAddresses()
}
}