我们公司有一个kerberos域,我正在运行一些Java / Kerberos examples。我的问题是从服务器的角度来看登录机制。运行服务器示例GssServer.java
时,我需要获得javax.security.auth.Subject
;在提供的代码中,这是通过LoginContext
因此:
// Create a LoginContext with a callback handler and login
LoginContext context = new LoginContext(name, new TextCallbackHandler());
context.login();
Subject subject = context.getSubject();
这一切都很好,当我运行示例时,我看到一个可爱的登录提示。但是我的问题是,不真的是我的服务器将如何运行,也不知道我是如何理解我应该如何在kerberos域内提供服务。在GssServer
示例中,问题是我的服务器(读取:服务)不需要对KDC
进行身份验证,以便向客户端提供其服务。访问服务器端keytab
文件应该足以执行此操作。所以对于示例配置:
//jaas-krb5.conf
server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/home/myusr/my-server.keytab"
principal="myserv/mymachine.some.domain";
};
在Java代码中:
GSSManager manager = GSSManager.getInstance();
Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
GSSName gssName = manager.createName("myserv/mymachine.some.domain@THE.REALM.COM",
GSSName.NT_HOSTBASED_SERVICE);
GSSCredential serverCreds = manager.createCredential(gssName,
GSSCredential.DEFAULT_LIFETIME,
krb5Mechanism,
GSSCredential.ACCEPT_ONLY);
问题在于server
文件中的jaas-krb5.conf
信息不可用,除非我通过以下行验证自己:
Jaas.loginAndAction("server", action);
我不应该通过此身份验证!但如果我不认证自己,我最终会:
Exception in thread "main" GSSException: No valid credentials provided (Mechanism level: Attempt to obtain new ACCEPT credentials failed!)
at sun.security.jgss.krb5.Krb5AcceptCredential.getKeysFromSubject(Krb5AcceptCredential.java:188)
at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:73)
at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:77)
at sun.security.jgss.GSSManagerImpl.getCredentialElement(GSSManagerImpl.java:149)
at sun.security.jgss.GSSCredentialImpl.add(GSSCredentialImpl.java:389)
at sun.security.jgss.GSSCredentialImpl.<init>(GSSCredentialImpl.java:45)
at sun.security.jgss.GSSManagerImpl.createCredential(GSSManagerImpl.java:102)
at gsa.hk.GssServer$GssServerAction.run(GssServer.java:79)
at gsa.hk.GssServer.main(GssServer.java:57)
Caused by: javax.security.auth.login.LoginException: No LoginModules configured for com.sun.security.jgss.accept
at javax.security.auth.login.LoginContext.init(LoginContext.java:256)
at javax.security.auth.login.LoginContext.<init>(LoginContext.java:403)
at sun.security.jgss.LoginUtility.login(LoginUtility.java:72)
at sun.security.jgss.krb5.Krb5Util.getKeysFromSubject(Krb5Util.java:205)
at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:184)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.jgss.krb5.Krb5AcceptCredential.getKeysFromSubject(Krb5AcceptCredential.java:181)
... 8 more
出现问题并不奇怪。毕竟,除非我处理server
主题,否则我怎么知道keytab
的位置,或者我提供的服务?
所以我的问题是:如果不在代码中验证自己,如何告诉GSS API
关键字/服务?
答案 0 :(得分:5)
行。因此,假设您知道可以使用keytab
文件而不是身份验证,那么非常容易。这在JavaDoc for Krb5LoginModule
基本上,如果我
loginAndAction("anything", action)
然后我的配置应该如下:
//jaas-krb5.conf
anything {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
doNotPrompt=true
keyTab="/home/myusr/my-server.keytab"
principal="myserv/mymachine.some.domain";
};
重要的是添加 doNotPrompt=true
。设置此属性后,服务器代码将使用keytab中的信息