auth conf

This commit is contained in:
Kent Yao 2020-10-26 17:59:01 +08:00
parent 11fd6f9263
commit 7864f6210a
8 changed files with 157 additions and 98 deletions

View File

@ -18,11 +18,13 @@
package org.apache.kyuubi.config
import java.time.Duration
import java.util.Locale
import java.util.concurrent.ConcurrentHashMap
import scala.collection.JavaConverters._
import org.apache.kyuubi.{Logging, Utils}
import org.apache.kyuubi.service.authentication.{AuthTypes, SaslQOP}
case class KyuubiConf(loadSysDefault: Boolean = true) extends Logging {
private val settings = new ConcurrentHashMap[String, String]()
@ -224,6 +226,77 @@ object KyuubiConf {
.timeConf
.createWithDefault(Duration.ofMillis(100).toMillis)
val AUTHENTICATION_METHOD: ConfigEntry[String] = buildConf("authentication")
.doc("Client authentication types." +
" NONE: no authentication check." +
" KERBEROS: Kerberos/GSSAPI authentication." +
" LDAP: Lightweight Directory Access Protocol authentication.")
.version("1.0.0")
.stringConf
.transform(_.toUpperCase(Locale.ROOT))
.checkValues(AuthTypes.values.map(_.toString))
.createWithDefault(AuthTypes.NONE.toString)
val AUTHENTICATION_LDAP_URL: OptionalConfigEntry[String] = buildConf("authentication.ldap.url")
.doc("SPACE character separated LDAP connection URL(s).")
.version("1.0.0")
.stringConf
.createOptional
val AUTHENTICATION_LDAP_BASEDN: OptionalConfigEntry[String] =
buildConf("authentication.ldap.base.dn")
.doc("LDAP base DN.")
.version("1.0.0")
.stringConf
.createOptional
val AUTHENTICATION_LDAP_DOMAIN: OptionalConfigEntry[String] =
buildConf("authentication.ldap.domain")
.doc("LDAP base DN.")
.version("1.0.0")
.stringConf
.createOptional
val DELEGATION_KEY_UPDATE_INTERVAL: ConfigEntry[Long] =
buildConf("delegation.key.update.interval")
.doc("")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofDays(1).toMillis)
val DELEGATION_TOKEN_MAX_LIFETIME: ConfigEntry[Long] =
buildConf("delegation.token.max.lifetime")
.doc("")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofDays(7).toMillis)
val DELEGATION_TOKEN_GC_INTERVAL: ConfigEntry[Long] =
buildConf("delegation.token.gc.interval")
.doc("")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofHours(1).toMillis)
val DELEGATION_TOKEN_RENEW_INTERVAL: ConfigEntry[Long] =
buildConf("delegation.token.renew.interval")
.doc("")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofDays(7).toMillis)
val SASL_QOP: ConfigEntry[String] = buildConf("sasl.qop")
.doc("Sasl QOP enable higher levels of protection for Kyuubi communication with clients." +
" auth - authentication only (default)" +
" auth-int - authentication plus integrity protection" +
" auth-conf - authentication plus integrity and confidentiality protectionThis is" +
" applicable only if Kyuubi is configured to use Kerberos authentication.")
.version("1.0.0")
.stringConf
.checkValues(SaslQOP.values.map(_.toString))
.transform(_.toLowerCase(Locale.ROOT))
.createWithDefault(SaslQOP.AUTH.toString)
/////////////////////////////////////////////////////////////////////////////////////////////////
// SQL Engine Configuration //
/////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -32,6 +32,7 @@ import org.apache.thrift.transport.{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.AuthTypes._
class KyuubiAuthenticationFactory(conf: KyuubiConf) {

View File

@ -20,6 +20,7 @@ package org.apache.kyuubi.service.authentication
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.config.KyuubiConf._
case class KyuubiDelegationTokenManager(
keyUpdateInterval: Long,

View File

@ -24,6 +24,7 @@ import javax.security.sasl.AuthenticationException
import org.apache.commons.lang.StringUtils
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.config.KyuubiConf._
import org.apache.kyuubi.service.ServiceUtils
class LdapAuthenticationProviderImpl(conf: KyuubiConf) extends PasswdAuthenticationProvider {

View File

@ -1,98 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.kyuubi.service
import java.time.Duration
import java.util.Locale
import org.apache.kyuubi.config.{ConfigEntry, OptionalConfigEntry}
import org.apache.kyuubi.config.KyuubiConf._
package object authentication {
val AUTHENTICATION_METHOD: ConfigEntry[String] = buildConf("authentication")
.doc("Client authentication types." +
" NONE: no authentication check." +
" KERBEROS: Kerberos/GSSAPI authentication." +
" LDAP: Lightweight Directory Access Protocol authentication.")
.version("1.0.0")
.stringConf
.transform(_.toUpperCase(Locale.ROOT))
.checkValues(AuthTypes.values.map(_.toString))
.createWithDefault(AuthTypes.NONE.toString)
val AUTHENTICATION_LDAP_URL: OptionalConfigEntry[String] = buildConf("authentication.ldap.url")
.doc("SPACE character separated LDAP connection URL(s).")
.version("1.0.0")
.stringConf
.createOptional
val AUTHENTICATION_LDAP_BASEDN: OptionalConfigEntry[String] =
buildConf("authentication.ldap.base.dn")
.doc("LDAP base DN.")
.version("1.0.0")
.stringConf
.createOptional
val AUTHENTICATION_LDAP_DOMAIN: OptionalConfigEntry[String] =
buildConf("authentication.ldap.domain")
.doc("LDAP base DN.")
.version("1.0.0")
.stringConf
.createOptional
val DELEGATION_KEY_UPDATE_INTERVAL: ConfigEntry[Long] =
buildConf("delegation.key.update.interval")
.doc("")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofDays(1).toMillis)
val DELEGATION_TOKEN_MAX_LIFETIME: ConfigEntry[Long] =
buildConf("delegation.token.max.lifetime")
.doc("")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofDays(7).toMillis)
val DELEGATION_TOKEN_GC_INTERVAL: ConfigEntry[Long] =
buildConf("delegation.token.gc.interval")
.doc("")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofHours(1).toMillis)
val DELEGATION_TOKEN_RENEW_INTERVAL: ConfigEntry[Long] =
buildConf("delegation.token.renew.interval")
.doc("")
.version("1.0.0")
.timeConf
.createWithDefault(Duration.ofDays(7).toMillis)
val SASL_QOP: ConfigEntry[String] = buildConf("sasl.qop")
.doc("Sasl QOP enable higher levels of protection for Kyuubi communication with clients." +
" auth - authentication only (default)" +
" auth-int - authentication plus integrity protection" +
" auth-conf - authentication plus integrity and confidentiality protectionThis is" +
" applicable only if Kyuubi is configured to use Kerberos authentication.")
.version("1.0.0")
.stringConf
.checkValues(SaslQOP.values.map(_.toString))
.transform(_.toLowerCase(Locale.ROOT))
.createWithDefault(SaslQOP.AUTH.toString)
}

View File

@ -0,0 +1,79 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.kyuubi.service.authentication
import java.security.Security
import javax.security.auth.login.LoginException
import org.apache.kyuubi.{KyuubiFunSuite, KyuubiSQLException}
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.service.authentication.PlainSASLServer.SaslPlainProvider
import org.apache.kyuubi.util.KyuubiHadoopUtils
class KyuubiAuthenticationFactorySuite extends KyuubiFunSuite {
import KyuubiAuthenticationFactory._
test("verify proxy access") {
val kyuubiConf = KyuubiConf()
val hadoopConf = KyuubiHadoopUtils.newHadoopConf(kyuubiConf)
val e1 = intercept[KyuubiSQLException] {
verifyProxyAccess("kent", "yao", "localhost", hadoopConf)
}
assert(e1.getMessage === "Failed to validate proxy privilege of kent for yao")
kyuubiConf.set("kyuubi.hadoop.proxyuser.kent.groups", "*")
kyuubiConf.set("kyuubi.hadoop.proxyuser.kent.hosts", "*")
val hadoopConf2 = KyuubiHadoopUtils.newHadoopConf(kyuubiConf)
verifyProxyAccess("kent", "yao", "localhost", hadoopConf2)
}
test("AuthType NONE") {
val kyuubiConf = KyuubiConf()
val auth = new KyuubiAuthenticationFactory(kyuubiConf)
auth.getTTransportFactory
assert(Security.getProviders.exists(_.isInstanceOf[SaslPlainProvider]))
assert(auth.getIpAddress.isEmpty)
assert(auth.getRemoteUser.isEmpty)
}
test("AuthType Other") {
val conf = KyuubiConf().set(KyuubiConf.AUTHENTICATION_METHOD, "INVALID")
val e = intercept[IllegalArgumentException](new KyuubiAuthenticationFactory(conf))
assert(e.getMessage === "The value of kyuubi.authentication should be one of" +
" KERBEROS, LDAP, NONE, NOSASL, but was INVALID")
}
test("AuthType LDAP") {
val conf = KyuubiConf().set(KyuubiConf.AUTHENTICATION_METHOD, "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_METHOD, "KERBEROS")
val factory = new KyuubiAuthenticationFactory(conf)
val e = intercept[LoginException](factory.getTTransportFactory)
assert(e.getMessage startsWith "Kerberos principal should have 3 parts")
}
}

View File

@ -41,6 +41,7 @@ import org.apache.mina.util.AvailablePortFinder
import org.apache.kyuubi.{KyuubiFunSuite, Utils}
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.config.KyuubiConf._
class LdapAuthenticationProviderImplSuite extends KyuubiFunSuite {

View File

@ -19,6 +19,7 @@ package org.apache.kyuubi.service.authentication
import org.apache.kyuubi.KyuubiFunSuite
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.config.KyuubiConf.SASL_QOP
class SaslQOPSuite extends KyuubiFunSuite {