2013-06-14 30 views
7

tôi đang cố gắng đăng nhập kerberos kdc từ Java. Nhưng Java đang ném ngoại lệ. Có vẻ như đăng nhập thành công nhưng một cái gì đó dừng lại đăng nhập. Tôi không biết tại sao? Ai đó có giải pháp cho vấn đề này? Đây là sản lượng hệ thống java của tôi:Kerberos với 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 [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 

Và mã java của tôi:

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

Không trả lời câu hỏi, nhưng không ném một 'Lỗi' trong' TicketCreatorAction # run() 'một chút bạo lực? – fge

+0

byte cuối cùng [] outToken = context.initSecContext (byte mới [0], 0, 0); tôi có ngoại lệ ném trên dòng này. –

Trả lời

2

tôi đã không kiểm tra mã của bạn, nhưng đọc stacktrace Tôi tin rằng vấn đề là với miền KDC. Như documentation says:

lĩnh vực mặc định và KDC cho lĩnh vực được nêu trong Kerberos krb5.conf

thường KDC lĩnh vực trong krb5.conf là kdc. Ví dụ từ cài đặt fedora mặc định:

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

tôi dường như rõ ràng rằng bạn nên thay đổi miền kdc của bạn với tên miền, không phải tên Realm:

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

Bạn đang sử dụng Kerberos trên máy tính địa phương, bạn có thể muốn thêm tùy chọn dns_lookup_kdc = false vào krb5.conf của bạn

+1

Tôi đã thay đổi ứng dụng StringPrincipal = "[email protected]"; final String ticket = retrieveTicket ("EXAMPLE.COM", "EXAMPLE.COM", applicationPrincipal); applicationPrincipal = "[email protected]" đã khắc phục sự cố.Cảm ơn –

+0

@Kadir bạn nên viết như một lời cảm ơn .... cảm ơn! – OhadR

Các vấn đề liên quan