cloudera manager下的hive权限配置
公司运营、BI以及财务不同部门不同人员需要hive数据查询服务,所以需要分配不同的权限给相关人员
权限配置主要涉及两项:
- 认证(authentication):验证用户所用的身份是否是对的
- 授权(authorization):验证用户所用身份操作是否有权限
cloudera集成的hive认证支持常用的LDAP和kerberos,授权使用的是他自家的sentry,sentry目前还处在孵化中。为了推广他自家的产品,屏蔽了hive的授权管理
针对我的需求,用户统一在hue界面操作hive,分配不同表权限给不同的用户,权限的授予只需要一个管理员账户;授权使用hive原生的
配置
认证配置
hive默认所有用户都可以做权限的更改,配置为只有管理员(如admin)才能修改权限
使用钩子做身份拦截,如果用户不为admin且操作权限管理操作,拒绝,代码示例如下: <code class="language-java hljs has-numbering"><span class="hljs-keyword">import</span> org.apache.commons.logging.Log; <span class="hljs-keyword">import</span> org.apache.commons.logging.LogFactory; <span class="hljs-keyword">import</span> org.apache.hadoop.hive.ql.parse.ASTNode; <span class="hljs-keyword">import</span> org.apache.hadoop.hive.ql.parse.AbstractSemanticAnalyzerHook; <span class="hljs-keyword">import</span> org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext; <span class="hljs-keyword">import</span> org.apache.hadoop.hive.ql.parse.SemanticException; <span class="hljs-keyword">import</span> org.apache.hadoop.hive.ql.session.SessionState; <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HiveAdmin</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractSemanticAnalyzerHook</span> {</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String admin = <span class="hljs-string">"admin"</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Log LOG = LogFactory.getLog(HiveAdmin.class); <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> ASTNode <span class="hljs-title">preAnalyze</span>(HiveSemanticAnalyzerHookContext context, ASTNode ast) <span class="hljs-keyword">throws</span> SemanticException { String userName = <span class="hljs-keyword">null</span>; String Authenticator=<span class="hljs-string">"null"</span>; <span class="hljs-keyword">switch</span> (ast.getToken().getType()) { <span class="hljs-keyword">case</span> <span class="hljs-number">692</span>: <span class="hljs-comment">//grant</span> <span class="hljs-keyword">case</span> <span class="hljs-number">646</span>:<span class="hljs-comment">// CREATE ROLE amengzi;</span> <span class="hljs-keyword">case</span> <span class="hljs-number">675</span>:<span class="hljs-comment">// DROP ROLE amengzi</span> <span class="hljs-keyword">case</span> <span class="hljs-number">694</span>: <span class="hljs-comment">//GRANT ROLE amengzi to user amengzi;</span> <span class="hljs-keyword">case</span> <span class="hljs-number">793</span>:<span class="hljs-comment">// REVOKE ROLE amengzi FROM user amengzi;</span> <span class="hljs-comment">// case 647://create table test11(id string)</span> <span class="hljs-comment">// case 676://drop table test;</span> <span class="hljs-comment">// case 783://select * from test;</span> <span class="hljs-comment">// case 817://show grant</span> <span class="hljs-comment">// case 671: //drop database;</span> <span class="hljs-keyword">if</span> (SessionState.get() != <span class="hljs-keyword">null</span> && SessionState.get().getAuthenticator() != <span class="hljs-keyword">null</span>) { Authenticator = SessionState.get().getAuthenticator().toString(); userName = SessionState.get().getAuthenticator().getUserName(); } <span class="hljs-keyword">if</span> (!admin.equalsIgnoreCase(userName)) { System.out.println(<span class="hljs-string">"===================can't use ADMIN options, except"</span>); <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> SemanticException(userName + <span class="hljs-string">" can't use ADMIN options, except "</span> + admin + <span class="hljs-string">"."</span>); } <span class="hljs-keyword">break</span>; <span class="hljs-keyword">default</span>: <span class="hljs-keyword">break</span>; } <span class="hljs-keyword">int</span> tokeType=ast.getToken().getType(); LOG.error(<span class="hljs-string">"tokeType:"</span>+tokeType+<span class="hljs-string">"=======user "</span> + SessionState.get().getAuthenticator().getUserName()+<span class="hljs-string">" Authenticator "</span>+SessionState.get().getAuthenticator().toString()); System.out.println(<span class="hljs-string">"tokeType:"</span>+tokeType+<span class="hljs-string">"===================user: "</span> + SessionState.get().getAuthenticator().getUserName()+<span class="hljs-string">" Authenticator "</span>+SessionState.get().getAuthenticator().toString()); <span class="hljs-keyword">return</span> ast; <span class="hljs-comment">// return super.preAnalyze(context, ast);</span> } <span class="hljs-comment">// @Override</span> <span class="hljs-comment">// public void postAnalyze(HiveSemanticAnalyzerHookContext context,</span> <span class="hljs-comment">// List<Task<? extends Serializable>> rootTasks)</span> <span class="hljs-comment">// throws SemanticException {</span> <span class="hljs-comment">// console.printInfo("!! SimpleSemanticPreAnalyzerHook postAnalyze called !!");</span> <span class="hljs-comment">// super.postAnalyze(context, rootTasks);</span> <span class="hljs-comment">// }</span> }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li></ul>
在使用客户端hive时,会显示向控制台输出的语句,便于调试
在hue上操作时,logger的输出会在hiveserver2日志中输出
授权配置
cloudera默认用org.apache.hadoop.hive.ql.parse.authorization.RestrictedHiveAuthorizationTaskFactoryImpl
替换hive的org.apache.hadoop.hive.ql.parse.authorization.HiveAuthorizationTaskFactoryImpl
做权限屏蔽,需要通过配置文件使用原生hive类
从CM界面放入以下配置于hive-site.xml 的 Hive 客户端高级配置代码段(安全阀)和hive-site.xml 的 HiveServer2 高级配置代码段(安全阀) <code class="hljs xml has-numbering"><span class="hljs-tag"><<span class="hljs-title">property</span>></span> <span class="hljs-tag"><<span class="hljs-title">name</span>></span>hive.security.authorization.enabled<span class="hljs-tag"></<span class="hljs-title">name</span>></span> <span class="hljs-tag"><<span class="hljs-title">value</span>></span>true<span class="hljs-tag"></<span class="hljs-title">value</span>></span> <span class="hljs-tag"><<span class="hljs-title">description</span>></span>enable or disable the hive client authorization<span class="hljs-tag"></<span class="hljs-title">description</span>></span> <span class="hljs-tag"></<span class="hljs-title">property</span>></span> <span class="hljs-tag"><<span class="hljs-title">property</span>></span> <span class="hljs-tag"><<span class="hljs-title">name</span>></span>hive.security.authorization.createtable.owner.grants<span class="hljs-tag"></<span class="hljs-title">name</span>></span> <span class="hljs-tag"><<span class="hljs-title">value</span>></span>ALL<span class="hljs-tag"></<span class="hljs-title">value</span>></span> <span class="hljs-tag"><<span class="hljs-title">description</span>></span>the privileges automatically granted to the owner whenever a table gets created. An example like"select,drop" will grant select and drop privilege to the owner of the table<span class="hljs-tag"></<span class="hljs-title">description</span>></span> <span class="hljs-tag"></<span class="hljs-title">property</span>></span> <span class="hljs-tag"><<span class="hljs-title">property</span>></span> <span class="hljs-tag"><<span class="hljs-title">name</span>></span>hive.security.authorization.task.factory<span class="hljs-tag"></<span class="hljs-title">name</span>></span> <span class="hljs-tag"><<span class="hljs-title">value</span>></span>org.apache.hadoop.hive.ql.parse.authorization.HiveAuthorizationTaskFactoryImpl<span class="hljs-tag"></<span class="hljs-title">value</span>></span> <span class="hljs-tag"></<span class="hljs-title">property</span>></span> <span class="hljs-tag"><<span class="hljs-title">property</span>></span> <span class="hljs-tag"><<span class="hljs-title">name</span>></span>hive.semantic.analyzer.hook<span class="hljs-tag"></<span class="hljs-title">name</span>></span> <span class="hljs-tag"><<span class="hljs-title">value</span>></span>HiveAdmin<span class="hljs-tag"></<span class="hljs-title">value</span>></span> <span class="hljs-tag"></<span class="hljs-title">property</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul>
注意:后续hdfs权限需要做相应修改
在namenode活动节点创建需要的用户账户
如果使用hue,linux账户和hue的账户可以同步hue useradmin_sync_with_unix
启用了hive权限之后发现hue和hive客户端都没有创建数据库的权限,我需要客户端能过创建数据酷,所以“hive-site.xml 的 Hive 客户端高级配置代码段(安全阀)“不作配置,这样HiveAdmin的jar包只需放到hiveserver2所在主机/opt/cloudera/parcels/CDH-5.4.4-1.cdh5.4.4.p0.4/lib/hive/lib/
下就可以,如果hive-site客户端也配置了权限,则jar需要放到hive lib下
如果想后端也加上权限,又想可以创建数据库,则方案可以配置为单独一台机子不做权限配置,用来做数据库创建
hue和hive有一个坑导致不能相同授权重复,所以授权操作需要通过hive客户端来操作