统一认证工具类
功能简介
LoginUtil类是一个安全认证工具类,主要功能是:提供Kerberos认证接口,并提供构造连接ZooKeeper组件所需Jaas配置信息对象的辅助类。LoginUtil类对外公开三个核心方法:login()方法、setJaasConf()方法和setZookeeperServerPrincipal()方法。
- Login()方法:认证接口。传入的参数包含用户名、keytab信息、krb5信息和业务配置信息。
- setJaasConf()方法:构造连接ZooKeeper组件所需Jaas配置信息对象并将其设置到内存中。
- setZookeeperServerPrincipal()方法:设置本应用所需访问的ZooKeeper服务名(即ZooKeeper组件启动时向Kerberos注册的名字)。连接ZooKeeper组件时,Kerberos认证需包含以上信息。
- JaasConfiguration类:私有类,用于辅助构造Jaas配置信息。支持Oracle JAVA 平台和IBM JAVA平台。
代码样例
1、login()方法
public synchronized static void login(String userPrincipal, String userKeytabPath, String krb5ConfPath, Configuration conf)
throws IOException
{
//检查传入参数合法性
……
// 3.set and check krb5config
setKrb5Config(krb5ConfFile.getAbsolutePath());
setConfiguration(conf);
// 4.check need login
if (checkNeedLogin(userPrincipal))
{
// 5.login and check for hadoop
loginHadoop(userPrincipal, userKeytabFile.getAbsolutePath());
}
// 6.check for relogin
checkAuthenticateOverKrb();
System.out.println("Login success!!!!!!!!!!!!!!");
}
说明:
- 代码注释已经对每个步骤有详细的描述。
- 必须先初始化配置,完成认证所需要的各类信息,最后才执行认证,各个步骤顺序不能出错。
- checkNeedLogin(userPrincipal)方法用于校验是否已经使用Kerberos用户登录过。若操作系统用户认证也是采用Kerberos机制,可能会影响此方法的判断结果。例如,华为桌面云采用IBM JAVA 平台,该环境中此方法会判断操作系统用户已经登录。若经过检查,确实不需要再做判断,可以将此方法注释掉。
2、loginHadoop()方法
private static void loginHadoop(String principal, String keytabFile)
throws IOException
{
try
{
UserGroupInformation.loginUserFromKeytab(principal, keytabFile);
}
catch (IOException e)
{
LOG.error("login failed with " + principal + " and " + keytabFile + ".");
LOG.error("perhaps cause 1 is " + LOGIN_FAILED_CAUSE_PASSWORD_WRONG + ".");
LOG.error("perhaps cause 2 is " + LOGIN_FAILED_CAUSE_TIME_WRONG + ".");
LOG.error("perhaps cause 3 is " + LOGIN_FAILED_CAUSE_AES256_WRONG + ".");
LOG.error("perhaps cause 4 is " + LOGIN_FAILED_CAUSE_PRINCIPAL_WRONG + ".");
LOG.error("perhaps cause 5 is " + LOGIN_FAILED_CAUSE_TIME_OUT + ".");
throw e;
}
}
说明:
- 认证API使用了UserGroupInformation.loginUserFromKeytab()方法。
- 导致认证失败的原因很多,本方法提供了安全认证中各个阶段可能的错误信息,便于定位和修复。
3、checkAuthenticateOverKrb()方法
private static void checkAuthenticateOverKrb()
throws IOException
{
UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
UserGroupInformation currentUser = UserGroupInformation.getCurrentUser();
if (loginUser == null)
{
LOG.error("current user is " + currentUser + ", but loginUser is null.");
throw new IOException("current user is " + currentUser + ", but loginUser is null.");
}
if (!loginUser.equals(currentUser))
{
LOG.error("current user is " + currentUser + ", but loginUser is " + loginUser + ".");
throw new IOException("current user is " + currentUser + ", but loginUser is " + loginUser + ".");
}
if (!loginUser.hasKerberosCredentials())
{
LOG.error("current user is " + currentUser + " has no Kerberos Credentials.");
throw new IOException("current user is " + currentUser + " has no Kerberos Credentials.");
}
if (!UserGroupInformation.isLoginKeytabBased())
{
LOG.error("current user is " + currentUser + " is not Login Keytab Based.");
throw new IOException("current user is " + currentUser + " is not Login Keytab Based.");
}
}
说明:
对认证结果进行详细检查。