auth conf
This commit is contained in:
parent
11fd6f9263
commit
7864f6210a
@ -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 //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user