17

ユーザー名とパスワードを含む Web フォームのコンテンツを取得し、kerberos を使用して Windows ベースのドメインを認証する Java ベースの Web アプリケーションがあります。

KDC アドレスはルックアップごとに異なる IP アドレスにマップするように設定されているようで、これはコマンド ラインから ping コマンドを使用して確認できます。

呼び出しは、ほとんどの要求に対してすぐに応答しますが、断続的に応答が遅くなります (5 ~ 10 秒またはそれ以上)。これは、使用しているドメイン コントローラーが原因である可能性があると思います。

Kerberos ログを有効にしようとしましたが、ドメイン コントローラーの IP アドレスが表示されません。危険なドメイン コントローラーを特定するために、より詳細なログを有効にするにはどうすればよいですか?

コード抽出は、ファイルシステムから kerb.conf と kerb_context.conf をソースします。

kerb.conf は次のとおりです。

[libdefaults]
default_realm = EXAMPLE.COM

[realms]
CYMRU.NHS.UK = {
        kdc = example.com:88
        admin_server = example.com
        kpasswd_server = example.com
}

kerb_context.conf は次のとおりです。

 primaryLoginContext {
        com.sun.security.auth.module.Krb5LoginModule required
        useTicketCache=false
        refreshKrb5Config=true
        debug=true;
};

ソースの例は次のとおりです。

static NadexUser executePerformLogin(String username, String password) throws LoginException {
            char[] passwd = password.toCharArray();
            String kerbConf = ERXFileUtilities.pathForResourceNamed("nadex/kerb.conf", "RSCorp", null);
            String kerbContextConf = ERXFileUtilities.pathURLForResourceNamed("nadex/kerb_context.conf", "RSCorp", null).toExternalForm();
            System.setProperty("java.security.krb5.conf", kerbConf);
            System.setProperty("java.security.auth.login.config", kerbContextConf);
            try {
                    LoginContext lc = new LoginContext("primaryLoginContext", new UserNamePasswordCallbackHandler(username, password));
                    lc.login();
                    return new _NadexUser(lc.getSubject());
            }
            catch (javax.security.auth.login.LoginException le) {
                    throw new LoginException("Failed to login : " + le.getLocalizedMessage(), le);
            }
    }
4

2 に答える 2

28

sun.security.krb5.debugシステム プロパティを に設定すると、ロギングを有効にできますtrue

Oracle のドキュメントを参照してください

于 2013-11-05T13:52:19.827 に答える
2

このような詳細なログを有効にする方法は見つかりませんでしたが、代わりに別のアプローチを採用することにしました。以下のコードは、同じディレクトリに jaas.conf 構成ファイルを必要とする自己完結型のアプリケーションです。

この短いテスト アプリケーションで使用する jaas.conf の例を次に示します。

primaryLoginContext {
        com.sun.security.auth.module.Krb5LoginModule required
        useTicketCache=false
        refreshKrb5Config=true
        debug=false;
};

このコードは、システム プロパティ sun.net.inetaddr.ttl を慎重に設定して、Java が DNS ルックアップの結果をキャッシュしないようにします。私の場合、DNS ルックアップはリクエストごとに変更されます。これはかなり大雑把なコードですが、ネットワーク内の構成が不十分な KDC や実行中の KDC を示します。

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;
import java.util.Vector;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;

public class TestNadex {
    private static final String DEFAULT_HOST = "cymru.nhs.uk";

    public static void main(String[] args) {
        System.setProperty("sun.net.inetaddr.ttl", "0");
        String username=null;
        String password=null;
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Enter username: ");
            username = br.readLine().trim();
            System.out.println("Enter password: ");
            password = br.readLine().trim();
            testHost(DEFAULT_HOST, username, password);
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

    static void testHost(String host, String username, String password) {
        HashMap<String, Vector<Long>> results = new HashMap<String, Vector<Long>>();
        for (int i=0; i<200; i++) {
            InetAddress ia;
            try {
                ia = InetAddress.getByName(host);
                long startTime = System.currentTimeMillis();
                executePerformLogin(ia.getHostAddress(), username, password);
                long endTime = System.currentTimeMillis();
                long duration = endTime - startTime;
                if (results.containsKey(ia.toString()) == false) {
                    Vector<Long> v = new Vector<Long>();
                    v.add(duration);
                    results.put(ia.toString(), v);
                }
                else {
                    Vector<Long> v = results.get(ia.toString());
                    v.add(duration);
                }
                Thread.sleep(1000);
            } catch (UnknownHostException e) {
                System.out.println("Unknown host: "  + host);
                System.exit(1);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        Set<String> keys = results.keySet();
        for (String key : keys) {
            System.out.println("For address: " + key);
            Vector<Long> times = results.get(key);
            int count = times.size();
            long total = 0;
            for (Long t : times) {
                System.out.println(t + " milliseconds");
                total += t;
            }
            System.out.println("Mean duration: " + new BigDecimal(total).divide(new BigDecimal(count), RoundingMode.HALF_UP));
        }
    }

    static void executePerformLogin(String hostname, String username, String password) throws MalformedURLException {
        System.setProperty("java.security.krb5.realm", "CYMRU.NHS.UK");
        System.setProperty("java.security.krb5.kdc", hostname);
        File jaas = new File("jaas.conf");
        String jaasconf = jaas.toURI().toURL().toExternalForm();
        System.setProperty("java.security.auth.login.config", jaasconf);
        //      System.setProperty("java.security.krb5.realm", "cymru.nhs.uk");
        //      System.setProperty("java.security.krb5.kdc", "cymru.nhs.uk");
        try {
            System.out.println("Performing NADEX login for username: " + username + " at " + new Date() + " to server " + hostname);
            LoginContext lc = new LoginContext("primaryLoginContext", new UserNamePasswordCallbackHandler(username, password));
            lc.login();
            System.out.println("Successful login for " + lc.getSubject().toString() + " at " + new Date());
        }
        catch (javax.security.auth.login.LoginException le) {
            System.err.println("Failed to login: " + le);
        }
    }

    public static class UserNamePasswordCallbackHandler implements CallbackHandler {
        private final String _userName;
        private final String _password;

        public UserNamePasswordCallbackHandler(String userName, String password) {
            _userName = userName;
            _password = password;
        }

        public void handle(Callback[] callbacks) throws IOException,
        UnsupportedCallbackException {
            for (Callback callback : callbacks) {
                if (callback instanceof NameCallback && _userName != null) {
                    ((NameCallback) callback).setName(_userName);
                }
                else if (callback instanceof PasswordCallback && _password != null) {
                    ((PasswordCallback) callback).setPassword(_password.toCharArray());
                }
            }
        }
    }
}
于 2013-03-14T14:35:42.910 に答える