设为首页 加入收藏

TOP

Kerberos Hadoop Java代码原理学习
2019-05-07 12:39:07 】 浏览:87
Tags:Kerberos Hadoop Java 代码 原理 学习

缘起

一直被这个三头恶犬欺负,今天我们分析一下它们的实现机制。

一提到kerberos,就会想起来一些概念,keytab, principal, tgt, ticket, KDC, JAAS, subject, credential, UGI, GSS等,概念难懂,代码也很难理解。

kerberos本身的概念这里就不分析了,自行看介绍。主要分析下java代码层面的东西。


初识UGI

首先,这里有个文章不错,大体分析了一下UGI这个对象的一些重要方法。

https://steveloughran.gitbooks.io/kerberos_and_hadoop/content/sections/ugi.html

这里需要对照UGI源码分析。


下面的是一个辅助理解UGI中group如何获得的文章,当然只是辅助,因为只是片面的理解

http://www.cnblogs.com/zwCHAN/p/4686054.html


如果看了代码,就会知道里面很多LoginContext, Subject, LoginModule, Credential之类的对象,其实都是来自于java的JAAS框架,要理清楚头绪,就要看看JAAS庐山真面目

初识JAAS

下面给出2个JAAS代码框架的例子

例子1

http://blog.csdn.net/xiao_jun_0820/article/details/39375819

Java的安全机制

详细介绍请参考JAAS:灵活的Java安全机制

简单来说,用户首先使用LoginContext的接口进行登录验证。LoginContext可以配置使用不同的验证协议。验证通过后,用户得到一个subject,里面包含凭证,公私钥等。之后,在涉及到需要进行权限认证的地方(例如,资源访问,外部链接校验,协议访问等),使用doAs函数()代替直接执行。

这样,java的权限认证就和用户的业务逻辑分离了。

    //一段典型的代码如下
    LoginContext lc = new LoginContext("MyExample");
    try {
    lc.login();
    } catch (LoginException) {
    // Authentication failed.
    }

    // Authentication successful, we can now continue.
    // We can use the returned Subject if we like.
    Subject sub = lc.getSubject();
    Subject.doAs(sub, new MyPrivilegedAction());


例子2

http://www.codeweblog.com/%E5%9F%BA%E4%BA%8Ekerberos%E5%AE%9E%E7%8E%B0jaas%E7%99%BB%E5%BD%95/

package security;

import java.io.File;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

public class KerberosClient {

    public static void main(String[] args) {
        String loginModuleName = "KerberosLogin";
        Subject subject = new Subject();
        Krb5Configuration conf = new Krb5Configuration();
        try {
            String sep = File.separator;
            System.out.println("KerberosClient.main():"
                    + System.getProperty("java.home") + sep + "lib" + sep
                    + "security" + sep + "java.security");
            LoginContext context = new LoginContext("myKerberosLogin", subject,
                    null, conf);
            context.login();
            System.out.println(context.getSubject().getPrincipals());

        } catch (LoginException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}


package security;

import java.util.HashMap;
import java.util.Map;

import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import javax.security.auth.login.Configuration;

public class Krb5Configuration extends Configuration{

    private AppConfigurationEntry[] entry = new AppConfigurationEntry[1];

    Map paramMap = new HashMap();

    private AppConfigurationEntry krb5LoginModule = new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", LoginModuleControlFlag.REQUIRED, paramMap);
    @Override
    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
        if(entry[0] == null){
            paramMap.put("debug", "true");

            //1.enter the username and passsword
            //paramMap.put("storeKey", "true");
            //paramMap.put("doNotPrompt", "false");

            //2.use keytab file
            paramMap.put("doNotPrompt", "true");
            paramMap.put("useKeyTab", "true");
            paramMap.put("keyTab", "/hadoop-data/etc/hadoop/nn.service.keytab");
            paramMap.put("principal", "nn/admin@psy.com");

            paramMap.put("useTicketCache", "true");
            paramMap.put("ticketCache", "/hadoop-data/etc/hadoop/keytab_cache");

            entry[0] = krb5LoginModule;
        }
        return entry;
    }

}



JAAS 框架图

jaas对象介绍

http://blog.sina.com.cn/s/blog_84feb25101015but.html

http://docs.huihoo.com/java/j2ee/jaas.html




LoginContext

javax/security/auth/login/LoginContext.java

/**
     * Perform the authentication.
     *
     * <p> This method invokes the <code>login</code> method for each
     * LoginModule configured for the <i>name</i> specified to the
     * <code>LoginContext</code> constructor, as determined by the login
     * <code>Configuration</code>.  Each <code>LoginModule</code>
     * then performs its respective type of authentication
     * (username/password, smart card pin verification, etc.).
     *
     * <p> This method completes a 2-phase authentication process by
     * calling each configured LoginModule's <code>commit</code> method
     * if the overall authentication succeeded (the relevant REQUIRED,
     * REQUISITE, SUFFICIENT, and OPTIONAL LoginModules succeeded),
     * or by calling each configured LoginModule's <code>abort</code> method
     * if the overall authentication failed.  If authentication succeeded,
     * each successful LoginModule's <code>commit</code> method associates
     * the relevant Principals and Credentials with the <code>Subject</code>.
     * If authentication failed, each LoginModule's <code>abort</code> method
     * removes/destroys any previously stored state.
     *
     * <p> If the <code>commit</code> phase of the authentication process
     * fails, then the overall authentication fails and this method
     * invokes the <code>abort</code> method for each configured
     * <code>LoginModule</code>.
     *
     * <p> If the <code>abort</code> phase
     * fails for any reason, then this method propagates the
     * original exception thrown either during the <code>login</code> phase
     * or the <code>commit</code> phase.  In either case, the overall
     * authentication fails.
     *
     * <p> In the case where multiple LoginModules fail,
     * this method propagates the exception raised by the first
     * <code>LoginModule</code> which failed.
     *
     * <p> Note that if this method enters the <code>abort</code> phase
     * (either the <code>login</code> or <code>commit</code> phase failed),
     * this method invokes all LoginModules configured for the
     * application regardless of their respective <code>Configuration</code>
     * flag parameters.  Essentially this means that <code>Requisite</code>
     * and <code>Sufficient</code> semantics are ignored during the
     * <code>abort</code> phase.  This guarantees that proper cleanup
     * and state restoration can take place.
     *
     * <p>
     *
     * @exception LoginException if the authentication fails.
     */
    public void login() throws LoginException {

        loginSucceeded = false;

        if (subject == null) {
            subject = new Subject();
        }

        try {
            // module invoked in doPrivileged
            invokePriv(LOGIN_METHOD);
            invokePriv(COMMIT_METHOD);
            loginSucceeded = true;
        } catch (LoginException le) {
            try {
                invokePriv(ABORT_METHOD);
            } catch (LoginException le2) {
                throw le;
            }
            throw le;
        }
    }

这里看一下注释,login的过程采用的是2PC,也就是两阶段提交


2阶段提交

http://www.hollischuang.com/archives/681

http://blog.csdn.net/whycold/article/details/47702133

http://www.hollischuang.com/archives/1580


2阶段提交3阶段提交,然后就是paxos协议,这是分布式系统中的常见保证原子性的机制

http://www.hollischuang.com/archives/693 paxos小解


说起了分布式系统,就顺便看看分布式锁吧

分布式锁的几种实现:http://www.hollischuang.com/archives/1716


http://www.hollischuang.com博客很不错




源码分析

UerGroupInformation.java

  /**
   * Information about the logged in user.
   */
  private static UserGroupInformation loginUser = null;
  private static String keytabPrincipal = null;
  private static String keytabFile = null;

  private final Subject subject;
  // All non-static fields must be read-only caches that come from the subject.
  private final User user;
  private final boolean isKeytab;
  private final boolean isKrbTkt;
  
  private static String OS_LOGIN_MODULE_NAME;
  private static Class< extends Principal> OS_PRINCIPAL_CLASS;
  

这里


下面的文章也很不错,相当于做了一个大致的梳理

https://my.oschina.net/drl/blog/676084

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Hadoop+Kylin集群部署过程和问题 下一篇hadoop reducer为空(不需要reduc..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目