Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
turboFei committed Oct 21, 2021
1 parent 8cc2ea6 commit 1aa30a5
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 66 deletions.
4 changes: 1 addition & 3 deletions docs/deployment/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,12 @@ You can configure the Kyuubi properties in `$KYUUBI_HOME/conf/kyuubi-defaults.co

Key | Default | Meaning | Type | Since
--- | --- | --- | --- | ---
kyuubi\.authentication|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>NONE</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>A comma separated list of client authentication types.<ul> <li>NOSASL: raw transport.</li> <li>NONE: no authentication check.</li> <li>KERBEROS: Kerberos/GSSAPI authentication.</li> <li>CUSTOM: User-defined authentication.</li> <li>LDAP: Lightweight Directory Access Protocol authentication.</li></ul></div>|<div style='width: 30pt'>seq</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.authentication<br>\.custom\.class|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>&lt;undefined&gt;</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>User-defined authentication implementation of org.apache.kyuubi.service.authentication.PasswdAuthenticationProvider</div>|<div style='width: 30pt'>string</div>|<div style='width: 20pt'>1.3.0</div>
kyuubi\.authentication<br>\.ldap\.base\.dn|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>&lt;undefined&gt;</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>LDAP base DN.</div>|<div style='width: 30pt'>string</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.authentication<br>\.ldap\.domain|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>&lt;undefined&gt;</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>LDAP domain.</div>|<div style='width: 30pt'>string</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.authentication<br>\.ldap\.guidKey|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>uid</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>LDAP attribute name whose values are unique in this LDAP server.For example:uid or cn.</div>|<div style='width: 30pt'>string</div>|<div style='width: 20pt'>1.2.0</div>
kyuubi\.authentication<br>\.ldap\.url|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>&lt;undefined&gt;</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>SPACE character separated LDAP connection URL(s).</div>|<div style='width: 30pt'>string</div>|<div style='width: 20pt'>1.0.0</div>
kyuubi\.authentication<br>\.sasl\.enabled|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>true</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>Whether enable SASL(GSSAPI or PLAIN) mechanism for authentication</div>|<div style='width: 30pt'>boolean</div>|<div style='width: 20pt'>1.4.0</div>
kyuubi\.authentication<br>\.sasl\.kerberos\.enabled|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>false</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>Whether enable KERBEROS: Kerberos/GSSAPI authentication</div>|<div style='width: 30pt'>boolean</div>|<div style='width: 20pt'>1.4.0</div>
kyuubi\.authentication<br>\.sasl\.plain\.auth\.type|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>&lt;undefined&gt;</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>Client authentication types for PLAIN mechanism.<ul> <li>NONE: no authentication check.</li> <li>CUSTOM: User-defined authentication.</li> <li>LDAP: Lightweight Directory Access Protocol authentication.</li></ul></div>|<div style='width: 30pt'>string</div>|<div style='width: 20pt'>1.4.0</div>
kyuubi\.authentication<br>\.sasl\.qop|<div style='width: 65pt;word-wrap: break-word;white-space: normal'>auth</div>|<div style='width: 170pt;word-wrap: break-word;white-space: normal'>Sasl QOP enable higher levels of protection for Kyuubi communication with clients.<ul> <li>auth - authentication only (default)</li> <li>auth-int - authentication plus integrity protection</li> <li>auth-conf - authentication plus integrity and confidentiality protection. This is applicable only if Kyuubi is configured to use Kerberos authentication.</li> </ul></div>|<div style='width: 30pt'>string</div>|<div style='width: 20pt'>1.0.0</div>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import scala.collection.JavaConverters._

import org.apache.kyuubi.{Logging, Utils}
import org.apache.kyuubi.engine.ShareLevel
import org.apache.kyuubi.service.authentication.{PlainAuthTypes, SaslQOP}
import org.apache.kyuubi.service.authentication.{AuthTypes, SaslQOP}

case class KyuubiConf(loadSysDefault: Boolean = true) extends Logging {
import KyuubiConf._
Expand Down Expand Up @@ -136,9 +136,7 @@ case class KyuubiConf(loadSysDefault: Boolean = true) extends Logging {
FRONTEND_THRIFT_BINARY_BIND_PORT,
FRONTEND_REST_BIND_HOST,
FRONTEND_REST_BIND_PORT,
AUTHENTICATION_SASL_ENABLED,
AUTHENTICATION_SASL_KERBEROS_ENABLED,
AUTHENTICATION_SASL_PLAIN_AUTH_TYPE,
AUTHENTICATION_METHOD,
SERVER_KEYTAB,
SERVER_PRINCIPAL,
KINIT_INTERVAL)
Expand Down Expand Up @@ -374,30 +372,20 @@ object KyuubiConf {
.version("1.4.0")
.fallbackConf(FRONTEND_LOGIN_BACKOFF_SLOT_LENGTH)

val AUTHENTICATION_SASL_ENABLED: ConfigEntry[Boolean] = buildConf("authentication.sasl.enabled")
.doc("Whether enable SASL(GSSAPI or PLAIN) mechanism for authentication")
.version("1.4.0")
.booleanConf
.createWithDefault(true)

val AUTHENTICATION_SASL_KERBEROS_ENABLED: ConfigEntry[Boolean] =
buildConf("authentication.sasl.kerberos.enabled")
.doc("Whether enable KERBEROS: Kerberos/GSSAPI authentication")
.version("1.4.0")
.booleanConf
.createWithDefault(false)

val AUTHENTICATION_SASL_PLAIN_AUTH_TYPE: OptionalConfigEntry[String] =
buildConf("authentication.sasl.plain.auth.type")
.doc("Client authentication types for PLAIN mechanism.<ul>" +
" <li>NONE: no authentication check.</li>" +
" <li>CUSTOM: User-defined authentication.</li>" +
" <li>LDAP: Lightweight Directory Access Protocol authentication.</li></ul>")
.version("1.4.0")
.stringConf
.transform(_.toUpperCase(Locale.ROOT))
.checkValues(PlainAuthTypes.values.map(_.toString))
.createOptional
val AUTHENTICATION_METHOD: ConfigEntry[Seq[String]] = buildConf("authentication")
.doc("A comma separated list of client authentication types.<ul>" +
" <li>NOSASL: raw transport.</li>" +
" <li>NONE: no authentication check.</li>" +
" <li>KERBEROS: Kerberos/GSSAPI authentication.</li>" +
" <li>CUSTOM: User-defined authentication.</li>" +
" <li>LDAP: Lightweight Directory Access Protocol authentication.</li></ul>")
.version("1.0.0")
.stringConf
.toSequence()
.transform(_.map(_.toUpperCase(Locale.ROOT)))
.checkValue(_.forall(AuthTypes.values.map(_.toString).contains),
s"the authentication type should be one or more of ${AuthTypes.values.mkString(",")}")
.createWithDefault(Seq(AuthTypes.NONE.toString))

val AUTHENTICATION_CUSTOM_CLASS: OptionalConfigEntry[String] =
buildConf("authentication.custom.class")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

package org.apache.kyuubi.service.authentication

object PlainAuthTypes extends Enumeration {
type PlainAuthType = Value
object AuthTypes extends Enumeration {
type AuthType = Value

val NONE, LDAP, CUSTOM = Value
val NOSASL, NONE, LDAP, KERBEROS, CUSTOM = Value
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,22 @@ import org.apache.hadoop.security.authentication.util.KerberosName
import org.apache.hadoop.security.authorize.ProxyUsers
import org.apache.hive.service.rpc.thrift.TCLIService.Iface
import org.apache.thrift.TProcessorFactory
import org.apache.thrift.transport.{TTransportException, TTransportFactory}
import org.apache.thrift.transport.{TSaslServerTransport, TTransportException, TTransportFactory}

import org.apache.kyuubi.KyuubiSQLException
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.config.KyuubiConf._
import org.apache.kyuubi.service.authentication.PlainAuthTypes._
import org.apache.kyuubi.service.authentication.AuthTypes._

class KyuubiAuthenticationFactory(conf: KyuubiConf) {
private val saslEnabled: Boolean = conf.get(AUTHENTICATION_SASL_ENABLED)
private val kerberosEnabled: Boolean = conf.get(AUTHENTICATION_SASL_KERBEROS_ENABLED)
private val plainAuthType: Option[PlainAuthType] =
conf.get(AUTHENTICATION_SASL_PLAIN_AUTH_TYPE).map(PlainAuthTypes.withName)

private val authTypes = conf.get(AUTHENTICATION_METHOD).map(AuthTypes.withName).toSet match {
case s if s == Set(NOSASL) => s
case s => s.filterNot(_.equals(NOSASL))
}

private val hadoopAuthServer: Option[HadoopThriftAuthBridgeServer] = {
if (saslEnabled && kerberosEnabled) {
if (authTypes.contains(KERBEROS)) {
val secretMgr = KyuubiDelegationTokenManager(conf)
try {
secretMgr.startThreads()
Expand All @@ -63,26 +64,32 @@ class KyuubiAuthenticationFactory(conf: KyuubiConf) {
}

def getTTransportFactory: TTransportFactory = {
if (!saslEnabled || (!kerberosEnabled && plainAuthType.isEmpty)) {
if (authTypes == Set(NOSASL)) {
new TTransportFactory()
} else {
val kerberosTransportFactory = hadoopAuthServer match {
var transportFactory: TSaslServerTransport.Factory = null

hadoopAuthServer match {
case Some(server) =>
val transportFactory = try {
transportFactory = try {
server.createSaslServerTransportFactory(getSaslProperties)
} catch {
case e: TTransportException => throw new LoginException(e.getMessage)
}
Some(transportFactory)

case _ => None
case _ =>
}

val transportFactory = plainAuthType.map { authType =>
PlainSASLHelper.getTransportFactory(authType.toString, conf, kerberosTransportFactory)
}.orElse(kerberosTransportFactory).orNull
authTypes.filterNot(at => at.equals(KERBEROS)).foreach { plainAuthType =>
transportFactory = PlainSASLHelper.getTransportFactory(plainAuthType.toString, conf,
Option(transportFactory)).asInstanceOf[TSaslServerTransport.Factory]
}

hadoopAuthServer match {
case Some(server) => server.wrapTransportFactory(transportFactory)

hadoopAuthServer.map(_.wrapTransportFactory(transportFactory)).getOrElse(transportFactory)
case _ => transportFactory
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,22 @@ class KyuubiAuthenticationFactorySuite extends KyuubiFunSuite {
}

test("AuthType Other") {
val conf = KyuubiConf().set(KyuubiConf.AUTHENTICATION_SASL_PLAIN_AUTH_TYPE, "INVALID")
val conf = KyuubiConf().set(KyuubiConf.AUTHENTICATION_METHOD, Seq("INVALID"))
val e = intercept[IllegalArgumentException](new KyuubiAuthenticationFactory(conf))
assert(e.getMessage === "The value of kyuubi.authentication.sasl.plain.auth.type should be" +
" one of CUSTOM, LDAP, NONE, but was INVALID")
assert(e.getMessage === "the authentication type should be one or more of" +
" NOSASL,NONE,LDAP,KERBEROS,CUSTOM")
}

test("AuthType LDAP") {
val conf = KyuubiConf().set(KyuubiConf.AUTHENTICATION_SASL_PLAIN_AUTH_TYPE, "LDAP")
val conf = KyuubiConf().set(KyuubiConf.AUTHENTICATION_METHOD, Seq("LDAP"))
val authFactory = new KyuubiAuthenticationFactory(conf)
authFactory.getTTransportFactory
assert(Security.getProviders.exists(_.isInstanceOf[SaslPlainProvider]))
}


test("AuthType KERBEROS w/o keytab/principal") {
val conf = KyuubiConf().set(KyuubiConf.AUTHENTICATION_SASL_KERBEROS_ENABLED, true)
val conf = KyuubiConf().set(KyuubiConf.AUTHENTICATION_METHOD, Seq("KERBEROS"))

val factory = new KyuubiAuthenticationFactory(conf)
val e = intercept[LoginException](factory.getTTransportFactory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,9 @@ object ServiceDiscovery extends Logging {
confsToPublish += ("hive.server2.thrift.port" -> hostPort(1))
confsToPublish += ("hive.server2.thrift.sasl.qop" -> conf.get(KyuubiConf.SASL_QOP))
// Auth specific confs
confsToPublish += ("hive.server2.authentication.sasl.enabled" ->
conf.get(KyuubiConf.AUTHENTICATION_SASL_ENABLED).toString)
confsToPublish += ("hive.server2.authentication.sasl.kerberos.enabled" ->
conf.get(KyuubiConf.AUTHENTICATION_SASL_KERBEROS_ENABLED).toString)
conf.get(KyuubiConf.AUTHENTICATION_SASL_PLAIN_AUTH_TYPE).foreach { plainAuthType =>
confsToPublish += ("hive.server2.authentication.sasl.plain.auth.type" -> plainAuthType)
}
if (conf.get(KyuubiConf.AUTHENTICATION_SASL_ENABLED) &&
conf.get(KyuubiConf.AUTHENTICATION_SASL_KERBEROS_ENABLED)) {
val authenticationMethod = conf.get(KyuubiConf.AUTHENTICATION_METHOD).mkString(",")
confsToPublish += ("hive.server2.authentication" -> authenticationMethod)
if (authenticationMethod.equalsIgnoreCase("KERBEROS")) {
confsToPublish += ("hive.server2.authentication.kerberos.principal" ->
conf.get(KyuubiConf.SERVER_PRINCIPAL).map(KyuubiHadoopUtils.getServerPrincipal)
.getOrElse(""))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ trait WithKyuubiServer extends KyuubiFunSuite {
conf.setIfMissing(ENGINE_IDLE_TIMEOUT, 10000L)
conf.set(HA_ZK_QUORUM, zkServer.getConnectString)
conf.set(HA_ZK_ACL_ENABLED, false)
conf.set(KyuubiConf.AUTHENTICATION_SASL_PLAIN_AUTH_TYPE, "NONE")

// TODO KYUUBI #745
conf.setIfMissing(ENGINE_INIT_TIMEOUT, 300000L)
Expand Down
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,6 @@
<sun.security.krb5.debug>false</sun.security.krb5.debug>
<kyuubi.operation.log.dir.root>target/server_operation_logs</kyuubi.operation.log.dir.root>
<kyuubi.engine.operation.log.dir.root>target/engine_operation_logs</kyuubi.engine.operation.log.dir.root>
<kyuubi.authentication.sasl.plain.auth.type>NONE</kyuubi.authentication.sasl.plain.auth.type>
</systemProperties>
<tagsToExclude>${maven.plugin.scalatest.exclude.tags}</tagsToExclude>
<tagsToInclude>${maven.plugin.scalatest.include.tags}</tagsToInclude>
Expand Down

0 comments on commit 1aa30a5

Please sign in to comment.