来自Tomcat / Catalina Applet的Kerberos keyTab身份验证

时间:2014-05-28 15:31:19

标签: java tomcat authentication kerberos jcifs

我在修改插件以支持Kerberos身份验证方面遇到了一个奇怪的难题。

使用密码和KRB5.conf(或ini)指定以下程序时,我可以成功验证主题。

但是,当运行以下程序进行本机身份验证时,keyTab可以正常运行。问题是我的程序,比如我们称之为kerbAuth.jar,是从 Tomcat中调用的。

import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

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

import jcifs.Config;
import jcifs.smb.Kerb5Authenticator;
import jcifs.smb.SmbFile;

import com.sun.security.auth.module.Krb5LoginModule;


public class testKRB 
{
    private static String URL = "smb://192.168.101.141/Share/";
    private static String KDC = "192.168.101.2";
    private static String REALM = "REALM.NET";
    private static String KRB = "/opt/app/config/krb5.ini";
    private static String KEYTAB = null;
    private static String PRINCIPAL = "user@REALM.NET";

    public static void main(String[] args) throws LoginException 
    {
        Console console = System.console();
        KEYTAB = console.readLine("Enter keytab path:");

        Config.setProperty("jcifs.smb.client.capabilities",Kerb5Authenticator.CAPABILITIES);
        Config.setProperty("jcifs.smb.client.flags2",Kerb5Authenticator.FLAGS2);
        Config.setProperty("jcifs.smb.client.signingPreferred", "true");

        try 
        {

            Subject subject = new Subject();
            login(subject);

            // List SMB files as a test.
            System.out.println("Files:");

            SmbFile file = new SmbFile(URL, new Kerb5Authenticator(subject));
            SmbFile[] files = file.listFiles();
            for( int i = 0; i < files.length; i++ ) {
                System.out.println( "-->" + files[i].getName() );
            }

        } catch (Exception e) 
        {
            e.printStackTrace();
        }
    }

    public static void login(Subject subject) throws LoginException
    {

        Map<String, Object> state = new HashMap<String, Object>();
        state.put("java.security.krb5.conf", KRB);

        Map<String, Object> option = new HashMap<String, Object>();
        option.put("debug", "true");
        option.put("debug", "true");
        option.put("principal", PRINCIPAL);
        option.put("useKeyTab", "true");
        option.put("keyTab", KEYTAB);
        option.put("refreshKrb5Config", "true");
        option.put("doNotPrompt", "true");
        option.put("storeKey", "true");


        Krb5LoginModule login = new Krb5LoginModule();
        login.initialize(subject, null, state, option);

        if(login.login())
        {
            login.commit();
        }
    }

上述解决方案在独立调用时效果很好。

从Tomcat中调用时,出现以下错误:

SEVERE: [Console] Error authenticating Subject: java.security.AccessControlException: access denied (javax.security.auth.AuthPermission modifyPrivateCredentials)

在进行登录提交后运行subject.getPrincipals().toString() ,我检索了Principal user@REALM.NET

查看KRB5调试日志:

Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is /opt/app/plugins/user.keytab refreshKrb5Config is false principal is user@REALM.NET tryFirstPass is false useFirstPass is false storePass is false clearPass is false
principal's key obtained from keytab
Aquire TGT using AS Exchange
principal is user@REALM.NET
EncryptionKey: keyType=18 keyBytes (hex dump)=0000; ......
java.security.AccessControlException: access denied (javax.security.auth.AuthPermission modifyPrivateCredentials)

这告诉我,我可以阅读keyTab就好了,我可以阅读校长(我认为是私人的,但如果我错了,请纠正我。)

为了解决AuthPermission错误,我做了两件事。

1)在我的主题初始化中添加了AuthPermissions:

state.put("javax.security.auth.AuthPermission", "doAs");
state.put("javax.security.auth.AuthPermission", "modifyPrincipals");
state.put("javax.security.auth.AuthPermission", "modifyPublicCredentials");
state.put("javax.security.auth.AuthPermission", "modifyPrivateCredentials");

2)将这些相同的权限添加到java.policy(在该Java空间中):

 grant codeBase "file:/opt/app/plugins/kerbAuth.jar"
 {
      permission javax.security.auth.AuthPermission "doAs";
      permission javax.security.auth.AuthPermission "modifyPrincipals";
      permission javax.security.auth.AuthPermission "modifyPublicCredentials";
      permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
 };

3)还尝试修改Catalina的manager.policy:

grant codeBase "file:/opt/app/tomcat/lib/-"
{
     permission javax.security.auth.AuthPermission "doAs";
     permission javax.security.auth.AuthPermission "modifyPrincipals";
     permission javax.security.auth.AuthPermission "modifyPublicCredentials";
     permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
};

然而,Catalina / Tomcat已经允许AllPermissions插件/小程序。

看起来storeKey调用是罪魁祸首的一部分,但如果不这样做,我必须将isInitiator设置为true以获得执行的提交(但不是实际上根据Wireshark与Active Directory通信,但TGT没有保存。

我正在寻找的是我可以在调试中采取的任何额外步骤,我需要设置AuthPermissions,无论是Tomcat还是其他类似,或者这是否是我在其他地方没有考虑的问题Tomcat中。

Java版本:1.6.0_31(应用程序的本机,而不是系统)

0 个答案:

没有答案