2013-06-14 4 views
7

자바에서 kerberos kdc에 로그인을 시도합니다. 그러나 Java는 예외를 던지고 있습니다. 로그인과 같아 보이지만 로그인이 중지됩니다. 이유를 모르겠습니다. 누군가이 문제의 해결책이 있습니까?자바가있는 Kerberos

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 [email protected] 
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 

그리고 내 자바 코드 : 여기 내 자바 시스템 출력

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>[email protected]</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); 
} 
} 
+0

질문에 대답하지는 않지만'TicketCreatorAction # run()'에 약간의 폭력을 던지지는 않습니까? – fge

+0

최종 바이트 [] outToken = context.initSecContext (새 바이트 [0], 0, 0); 이 줄에 예외가 발생했습니다. –

답변

2

난 당신의 코드를 테스트하지 못했지만, 스택 트레이스를 읽고 나는 문제가 KDC 도메인과 믿습니다. documentation says으로 :

기본 영역 및 그 영역의 KDC가 krb5.conf의에서 커버 로스 krb5.conf의 일반적

KDC 영역에 표시됩니다 kdc입니다. 페도라 기본 설치의 예 :

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

나는 분명한 것 같다 당신이 도메인 이름으로 kdc 도메인을 변경해야하지 영역 이름 : 당신은 로컬 컴퓨터에 Kerberos를 사용하는

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

, 당신에게 할 수 있습니다 dns_lookup_kdc = false을 krb5.conf에 추가하십시오.

+1

변경됨 String applicationPrincipal = "[email protected]"; final String ticket = retrieveTicket ("EXAMPLE.COM", "EXAMPLE.COM", applicationPrincipal); applicationPrincipal = "[email protected]"문제가 해결되었습니다. 감사합니다. –

+0

@ 카디르 (Khadir)는 asnwer ...로 작성해야합니다 .... 감사합니다! – OhadR