代理用户的概念
在Hadoop认证体系中有代理用户和鉴权用户的设计,其中代理用户用于安全认证,而鉴权用户则是实际访问服务/数据的用户,会用于鉴权与审计。
livy impersonate场景
一个典型的例子
在hue里面添加了通过livy提交spark任务的功能,并且livy是开启安全认证的。这个时候我们需要有一个公用的代理用户,并且这个代理用户将会对应多个鉴权用户,这个鉴权用户可以是hue的登录用户,用于鉴权和审计。
源码分析
LivyServer.scala 初始化session/batch,都带有accessManager
val interactiveServlet = new InteractiveSessionServlet(
interactiveSessionManager, sessionStore, livyConf, accessManager)
mount(context, interactiveServlet, "/sessions/*")
val batchServlet =
new BatchSessionServlet(batchSessionManager, sessionStore, livyConf, accessManager)
mount(context, batchServlet, "/batches/*")
InteractiveSessionServlet.scala 和 SessionServlet.scala,这里拿session举例(batch也是类似的),effectiveUser调用的是AccessManager的checkImpersonation方法
private def doWithSession(fn: (S => Any),
...
if (allowAll ||
checkFn.map(_(session.owner,
effectiveUser(request),
session.proxyUser.getOrElse("")))
.getOrElse(false)) {
fn(session)
}
AccessManager.scala 条件LivyConf.IMPERSONATION_ENABLED==true,并且(代理用户==鉴权用户 或 代理用户是超级用户,则需要增加配置livy.superusers)
def checkImpersonation(
target: Option[String],
requestUser: String): Option[String] = {
if (conf.getBoolean(LivyConf.IMPERSONATION_ENABLED)) {
if (!target.forall(hasSuperAccess(_, requestUser))) {
throw new AccessControlException(
s"User '$requestUser' not allowed to impersonate '$target'.")
}
target.orElse(Option(requestUser))
} else {
None
}
}
配置更新
livy.conf 修改下面两行配置,其中hadoop是我们的代理用户
livy.impersonation.enabled true
livy.superusers hadoop
hue 配置参考
目前无法在配置文件中加入认证信息,只能修改代码(Authorization使用base64.b64encode进行编码)
sudo vi /usr/lib/hue/apps/spark/src/spark/livy_client.py
if self.csrf_enabled:
self._client.set_headers({'X-Requested-By': 'hue'})
修改成
if self.csrf_enabled:
self._client.set_headers({'X-Requested-By': 'hue','Authorization':'Basic abdacsdsf'})