浏览 2253 次
锁定老帖子 主题:我对cdh4安全机制的解读
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2013-06-06
目测 AccessControlException比较像,然后看到他有个子类:AuthorizationException。这个受众更小,更容易做为切入点,好,就这个了。 public void authorize(UserGroupInformation user, Class<?> protocol, Configuration conf, InetAddress addr ) throws AuthorizationException { AccessControlList acl = protocolToAcl.get(protocol); if (acl == null) { throw new AuthorizationException("Protocol " + protocol + " is not known."); } // get client principal key to verify (if available) KerberosInfo krbInfo = SecurityUtil.getKerberosInfo(protocol, conf); String clientPrincipal = null; if (krbInfo != null) { String clientKey = krbInfo.clientPrincipal(); if (clientKey != null && !clientKey.equals("")) { try { clientPrincipal = SecurityUtil.getServerPrincipal( conf.get(clientKey), addr); } catch (IOException e) { throw (AuthorizationException) new AuthorizationException( "Can't figure out Kerberos principal name for connection from " + addr + " for user=" + user + " protocol=" + protocol) .initCause(e); } } } if((clientPrincipal != null && !clientPrincipal.equals(user.getUserName())) || !acl.isUserAllowed(user)) { AUDITLOG.warn(AUTHZ_FAILED_FOR + user + " for protocol=" + protocol + ", expected client Kerberos principal is " + clientPrincipal); throw new AuthorizationException("User " + user + " is not authorized for protocol " + protocol + ", expected client Kerberos principal is " + clientPrincipal); } AUDITLOG.info(AUTHZ_SUCCESSFUL_FOR + user + " for protocol="+protocol); } 这里是会抛出AuthorizationException异常的。 我比较关注kerberos的部分:clientPrincipal.equals(user.getUserName() clientPrincipal = SecurityUtil.getServerPrincipal( conf.get(clientKey), addr); KerberosInfo krbInfo = SecurityUtil.getKerberosInfo(protocol, conf); 关键是clientKey,但是clientKey需要krbInfo。所以krbInfo就是最关键的地方了。 for(SecurityInfo provider: securityInfoProviders) { KerberosInfo result = provider.getKerberosInfo(protocol, conf); 那这里是的securityInfoProviders是怎么来的呢: private static ServiceLoader<SecurityInfo> securityInfoProviders = ServiceLoader.load(SecurityInfo.class); 这里使用了ServiceLoader,我们看到hadoop-commom的META-INF\services文件夹,有个叫org.apache.hadoop.security.SecurityInfo的文件名,内容是 org.apache.hadoop.security.AnnotatedSecurityInfo。 public class AnnotatedSecurityInfo extends SecurityInfo { @Override public KerberosInfo getKerberosInfo(Class<?> protocol, Configuration conf) { return protocol.getAnnotation(KerberosInfo.class); } 意思就是返回protocol对应类的注解KerberosInfo 就可以了。 protocol = getProtocolClass(protocolName, getConf()); 这个类似根据protocolName反射得到的。 可以看到protocolName是从数据流中读取的, processOneRpc(data.array()); 这里的data就是protocolName的源头了。 现在能拿到clientKey,再回过头来。 clientPrincipal = SecurityUtil.getServerPrincipal( conf.get(clientKey), addr); 这里就与conf扯上关系了,conf的各个key和value都是系统初始化进去的。 clientPrincipal 只是conf对应的value替换掉主机名而已。看到替换规则,这些value应该是以[/@]来分隔的,但是我看了conf的初始化过程,没有找见有这样的value. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2013-06-09
厉害,楼主在广州哪里工作?
|
|
返回顶楼 | |