gpt4 book ai didi

java - Kerberos 与 Java

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:34:29 27 4
gpt4 key购买 nike

我正在尝试从 Java 登录 kerberos kdc。但是 Java 抛出异常。似乎登录成功,但有些东西停止登录。我不知道为什么?有人有解决这个问题的方法吗?这是我的 Java 系统输出:

Debug is  true storeKey false useTicketCache true useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is true principal is null tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
Acquire TGT from Cache
Principal is null
null credentials from Ticket Cache
[Krb5LoginModule] user entered username: kadirb

principal is kadirb@EXAMPLE.COM
Commit Succeeded

Exception in thread "main" java.lang.Error: GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER)
at KerberosTicketRetriever$TicketCreatorAction.run(KerberosTicketRetriever.java:76)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAsPrivileged(Subject.java:473)
at KerberosTicketRetriever.retrieveTicket(KerberosTicketRetriever.java:179)
at KerberosTicketRetriever.main(KerberosTicketRetriever.java:188)
Caused by: GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER)
at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:710)
at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248)
at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
at KerberosTicketRetriever$TicketCreatorAction.createTicket(KerberosTicketRetriever.java:105)
at KerberosTicketRetriever$TicketCreatorAction.run(KerberosTicketRetriever.java:72)
... 4 more
Caused by: KrbException: Server not found in Kerberos database (7) - LOOKING_UP_SERVER
at sun.security.krb5.KrbTgsRep.<init>(KrbTgsRep.java:73)
at sun.security.krb5.KrbTgsReq.getReply(KrbTgsReq.java:192)
at sun.security.krb5.KrbTgsReq.sendAndGetCreds(KrbTgsReq.java:203)
at sun.security.krb5.internal.CredentialsUtil.serviceCreds(CredentialsUtil.java:311)
at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(CredentialsUtil.java:115)
at sun.security.krb5.Credentials.acquireServiceCreds(Credentials.java:442)
at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:641)
... 8 more
Caused by: KrbException: Identifier doesn't match expected value (906)
at sun.security.krb5.internal.KDCRep.init(KDCRep.java:143)
at sun.security.krb5.internal.TGSRep.init(TGSRep.java:66)
at sun.security.krb5.internal.TGSRep.<init>(TGSRep.java:61)
at sun.security.krb5.KrbTgsRep.<init>(KrbTgsRep.java:55)
... 14 more
Disconnected from the target VM, address: '127.0.0.1:51126', transport: 'socket'

Process finished with exit code 1

还有我的java代码:

import com.sun.security.auth.callback.DialogCallbackHandler;
import org.ietf.jgss.*;
import sun.misc.BASE64Encoder;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.io.*;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Set;

/**
* Tool to retrieve a kerberos ticket. This one will not be stored in the windows ticket cache.
*/
public final class KerberosTicketRetriever
{
private final static Oid KERB_V5_OID;
private final static Oid KRB5_PRINCIPAL_NAME_OID;

static {
try
{
KERB_V5_OID = new Oid("1.2.840.113554.1.2.2");
KRB5_PRINCIPAL_NAME_OID = new Oid("1.2.840.113554.1.2.2.1");

} catch (final GSSException ex)
{
throw new Error(ex);
}
}

/**
* Not to be instanciated
*/
private KerberosTicketRetriever() {};

/**
*
*/
private static class TicketCreatorAction implements PrivilegedAction
{
final String userPrincipal;
final String applicationPrincipal;

private StringBuffer outputBuffer;

/**
*
* @param userPrincipal p.ex. <tt>MuelleHA@MYFIRM.COM</tt>
* @param applicationPrincipal p.ex. <tt>HTTP/webserver.myfirm.com</tt>
*/
private TicketCreatorAction(final String userPrincipal, final String applicationPrincipal)
{
this.userPrincipal = userPrincipal;
this.applicationPrincipal = applicationPrincipal;
}

private void setOutputBuffer(final StringBuffer newOutputBuffer)
{
outputBuffer = newOutputBuffer;
}

/**
* Only calls {@link #createTicket()}
* @return <tt>null</tt>
*/
public Object run()
{
try
{
createTicket();
}
catch (final GSSException ex)
{
throw new Error(ex);
}

return null;
}

/**
*
* @throws GSSException
*/
private void createTicket () throws GSSException
{
final GSSManager manager = GSSManager.getInstance();
final GSSName clientName = manager.createName(userPrincipal, KRB5_PRINCIPAL_NAME_OID);
final GSSCredential clientCred = manager.createCredential(clientName,
8 * 3600,
KERB_V5_OID,
GSSCredential.INITIATE_ONLY);

final GSSName serverName = manager.createName(applicationPrincipal, KRB5_PRINCIPAL_NAME_OID);

final GSSContext context = manager.createContext(serverName,
KERB_V5_OID,
clientCred,
GSSContext.DEFAULT_LIFETIME);
context.requestMutualAuth(true);
context.requestConf(false);
context.requestInteg(true);

final byte[] outToken = context.initSecContext(new byte[0], 0, 0);

if (outputBuffer !=null)
{
outputBuffer.append(String.format("Src Name: %s\n", context.getSrcName()));
outputBuffer.append(String.format("Target : %s\n", context.getTargName()));
outputBuffer.append(new BASE64Encoder().encode(outToken));
outputBuffer.append("\n");
}

context.dispose();
}
}

/**
*
* @param realm p.ex. <tt>MYFIRM.COM</tt>
* @param kdc p.ex. <tt>kerbserver.myfirm.com</tt>
* @param applicationPrincipal cf. {@link #TicketCreatorAction(String, String)}
* @throws GSSException
* @throws LoginException
*/
static public String retrieveTicket(
final String realm,
final String kdc,
final String applicationPrincipal)
throws GSSException, LoginException
{

// create the jass-config-file
final File jaasConfFile;
try
{
jaasConfFile = File.createTempFile("jaas.conf", null);
final PrintStream bos = new PrintStream(new FileOutputStream(jaasConfFile));
bos.print(String.format(
"Krb5LoginContext { com.sun.security.auth.module.Krb5LoginModule required refreshKrb5Config=true useTicketCache=true debug=true ; };"
));
bos.close();
jaasConfFile.deleteOnExit();
}
catch (final IOException ex)
{
throw new IOError(ex);
}

// set the properties
System.setProperty("java.security.krb5.realm", realm);
System.setProperty("java.security.krb5.kdc", kdc);
System.setProperty("java.security.auth.login.config",jaasConfFile.getAbsolutePath());

// get the Subject(), i.e. the current user under Windows
final Subject subject = new Subject();
final LoginContext lc = new LoginContext("Krb5LoginContext", subject, new DialogCallbackHandler());
try {
lc.login();
} catch (LoginException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
//e = Client not found in Kerberos database (6) - CLIENT_NOT_FOUND
System.exit(0);
}

// extract our principal
final Set<Principal> principalSet = subject.getPrincipals();
if (principalSet.size() != 1)
throw new AssertionError("No or several principals: " + principalSet);
final Principal userPrincipal = principalSet.iterator().next();

// now try to execute the SampleAction as the authenticated Subject
// action.run() without doAsPrivileged leads to
// No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
final TicketCreatorAction action = new TicketCreatorAction(userPrincipal.getName(), applicationPrincipal);
final StringBuffer outputBuffer = new StringBuffer();
action.setOutputBuffer(outputBuffer);
Subject.doAsPrivileged(lc.getSubject(), action, null);

return outputBuffer.toString();
}

public static void main (final String args[]) throws Throwable
{
final String ticket = retrieveTicket("EXAMPLE.COM", "EXAMPLE.COM", "HTTP/webserver.myfirm.com");
System.out.println(ticket);
}
}

最佳答案

我没有测试你的代码,但阅读堆栈跟踪我相信问题出在 KDC 域上。作为documentation says :

the default realm and the KDC for that realm are indicated in the Kerberos krb5.conf

通常 krb5.conf 中的 KDC 领域是 kdc。 fedora 默认安装示例:

[realms]
EXAMPLE.COM = {
kdc = kerberos.example.com
admin_server = kerberos.example.com
}

很明显,您应该使用域名而不是领域名称更改您的 kdc 域:

final String ticket = retrieveTicket("EXAMPLE.COM", "localhost", "HTTP/webserver.myfirm.com");

您在本地机器上使用 Kerberos,您可能需要将选项 dns_lookup_kdc = false 添加到您的 krb5.conf

关于java - Kerberos 与 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17102411/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com