我被被派去做别的事情了,所以与hadoop相关的工作就只能搁下。写篇总结,把最近遇到的和kerberos相关的东西列一下。

JAAS是Java 认证和授权服务(Java Authentication and Authorization Service)的缩写,是PAM框架的Java实现。
javax.sercurity.auth.Subject是一个不可继承的实体类,它表示单个实体的一组相关信息,与请求的来源相关。
javax.security.auth.Principal是一个接口,表示带有不同类型凭证的标识,基本上来说,Principal可以是任意对象。
JAAS的授权机制主要就是围绕着Subject和Principal。关于JAAS比较详细的参考是这里:http://docs.oracle.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html
几个比较重要的java属性:
java.security.krb5.realm
java.security.krb5.kdc
java.security.krb5.conf

hadoop的身份认证和授权都是建立在JAAS之上。
hadoop.security.authentication属性有2种值:
simple: Security is disabled。
kerberos: Security is enabled。
org.apache.hadoop.security.UserGroupInformation有一个静态方法:getCurrentUser()。它会返回一个UserGroupInformation类的实例(以下简称UGI)。如果subject为空,或者这个subject中与org.apache.hadoop.security.User对应的Principal为空,那么说明尚未登录过,调用getLoginUser()创建UserGroupInformation的实例。
getLoginUser()的流程:
1.创建LoginContext:
LoginContext是由UserGroupInformation.newLoginContext(String, Subject)方法创建的。LoginContext的name有三种取值:

  1. hadoop-user-kerberos
  2. hadoop-keytab-kerberos
  3. hadoop-simple 即没有启用kerberos认证

这个name的主要作用是作为appName传递给UserGroupInformation.HadoopConfiguration.getAppConfigurationEntry(String appName)方法。
kerberos具体的login逻辑,还是交给com.sun.security.auth.module.Krb5LoginModule完成的。
如果name是hadoop-user-kerberos,那么useTicketCache是true,否则是false。
如果useTicketCache是true,那么会从 /tmp/krb5cc_${uid}或者用户的home目录下krb5cc_${user.name}中读ticket信息。这种情况下,hadoop会创建一个新线程用kinit -R去刷新这个ticket cache(默认是总有效时间过了80%之后刷新),并且,jdk也会尝试利用它的ticket cache进行renew。
如果name是hadoop-keytab-kerberos,那么就没人帮忙renew了。

subject:
callbackHandler: 空
Configuration: UserGroupInformation.HadoopConfiguration的实例。
2.login.login();
这个会调用HadoopLoginModule的login()和commit()方法。
HadoopLoginModule的login()方法是一个空函数,只打印了一行调试日志 LOG.debug("hadoop login");
commit()方法负责把Principal添加到Subject中。
此时一个首要问题是username是什么?
在使用了kerberos的情况下,从javax.security.auth.kerberos.KerberosPrincipal的实例获取username。
在未使用kerberos的情况下,优先读取HADOOP_USER_NAME这个系统环境变量,如果不为空,那么拿它作username。否则,读取HADOOP_USER_NAME这个java环境变量。否则,从com.sun.security.auth.NTUserPrincipal或者com.sun.security.auth.UnixPrincipal的实例获取username。
如果以上尝试都失败,那么抛出异常LoginException("Can't find user name")。
最终拿username构造org.apache.hadoop.security.User的实例添加到Subject中。

测试登录:
HADOOP_JAAS_DEBUG=true HADOOP_ROOT_LOGGER=DEBUG,console bin/hadoop org.apache.hadoop.security.UserGroupInformation
其中,UGI应该是这样的形式:
UGI: host/xx.xx.xx.com@xx.xx.com (auth:KERBEROS)
如果是下面这样,就说明错了
12/03/28 18:44:52 DEBUG security.Groups: Returning fetched groups for 'app_admin'
Groups: app_admin
UGI: app_admin (auth:KERBEROS)
Auth method KERBEROS
Keytab false
据我观察,目前好像只有hadoop内部的通信可以用keytab。如果想在shell下执行bin/hdfs什么的,还是得手动调用kinit。而且,我不知道hadoop用keytab登录后,把Ticket cache放哪了。好像跟系统默认的不一样。

在执行kinit的时候,如果没有root权限,可以用KRB5_CONFIG这个环境变量来指定krb5.conf的位置。这个在kinit的文档中并没有提到,它只提到了KRB5CCNAME和KRBTKFILE。

最新文章

  1. SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句
  2. Stack与Queue
  3. 在集群上运行caffe程序时如何避免Out of Memory
  4. eclipse+android+opencv环境搭建的步骤
  5. html5学习笔记5--API Range对象(二)
  6. C#中的接口
  7. 生成中文版JavaDoc
  8. React如何性能调优
  9. poj3411Paid Roads(dfs)
  10. \\ip 映射 指定的网络名不再可用
  11. schedule() 和 scheduleAtFixedRate() 的区别--转载
  12. 响应式页面字体用什么单位:rem
  13. Game of Life 解答
  14. Shrio授权验证详解
  15. 59. Spiral Matrix II(中等,同54题)
  16. Object对象你真理解了吗?
  17. 为什么react的组件要super(props)
  18. 作为完美主义者(强迫症)如何将linux的eth1网卡修改为eth0网卡
  19. Autohotkey window 下宏键盘、宏命令开发入门
  20. 用scrapy爬取亚马逊网站项目

热门文章

  1. jsp内建对象的作用域
  2. 2019-2-27-如何替换一个-exe-的图标
  3. vue项目配置同一局域网可使用ip访问
  4. Android教程-01 Android Studio创建第一个项目
  5. hdu 5744 Keep On Movin (2016多校第二场)
  6. History和Location
  7. Python--day71--ORM分组补充
  8. php Restful设计
  9. [转]来自后端的逆袭 blazor简介 全栈的福音
  10. Flex AIR应用换肤功能(Android和IOS)