2008-12-16 11 views
11

क्या कोई जानता है कि जावा जीएसएस-एपीआई का उपयोग करके कुंजी वितरण केंद्र (केडीसी) से सर्विस टिकट कैसे प्राप्त करें?जीएसएस-एपीआई के माध्यम से केर्बेरोज सेवा टिकट कैसे प्राप्त करें?

मेरे पास एक मोटी-क्लाइंट-एप्लिकेशन है जो पहले टीएटीटी को टिकट कैश से लाने के लिए Krb5LoginModule का उपयोग करके जेएएएस के माध्यम से प्रमाणित करता है (पृष्ठभूमि: विंडोज उदा। केर्बेरोज कार्यान्वयन का उपयोग करता है और टिकट को सुरक्षित मेमोरी क्षेत्र में टिकट देने के लिए स्टोर करता है)। LoginManager से मुझे विषय वस्तु मिलती है जिसमें टीजीटी होता है। अब मुझे आशा है कि जब मैं अपनी सेवा के लिए एक विशिष्ट जीएसएस क्रेडेंशियल ऑब्जेक्ट बनाउंगा, तो सर्विस टिकट को विषय के निजी प्रमाण-पत्रों में भी रखा जाएगा (मैंने वेब में कहीं और पढ़ा है)। प्रदान की कोई मान्य क्रेडेंशियल्स (तंत्र का स्तर:: किसी भी करबरोस TGT को ढूंढने में विफल)

// Exception handling ommitted 
LoginContext lc = new LoginContext("HelloEjbClient", new DialogCallbackHandler()); 
lc.login() 
Subject.doAs(lc.getSubject(), new PrivilegedAction() { 

    public Object run() { 
     GSSManager manager = GSSManager.getInstance(); 
     GSSName clientName = manager.createName("clientUser", GSSName.NT_USER_NAME); 
     GSSCredential clientCreds = manager.createCredential(clientName, 8 * 3600, createKerberosOid(), GSSCredential.INITIATE_ONLY); 

     GSSName serverName = manager.createName("[email protected]", GSSName.NT_HOSTBASED_SERVICE); 
     manager.createCredential(serverName, GSSCredential.INDEFINITE_LIFETIME, createKerberosOid(), GSSCredential.INITIATE_ONLY); 
     return null; 
    } 

    private Oid createKerberosOid() { 
     return new Oid("1.2.840.113554.1.2.2"); 
    } 

}); 

दुर्भाग्य से मैं एक GSSException मिल: तो मैं निम्नलिखित की कोशिश की है।

उत्तर

14

सेवा टिकट प्राप्त करने की मेरी समझ गलत थी। मुझे सेवा से प्रमाण-पत्र प्राप्त करने की आवश्यकता नहीं है - क्लाइंट पर यह संभव नहीं है, क्योंकि क्लाइंट के पास वास्तव में सर्वर के लिए टीजीटी नहीं है और इसलिए सेवा प्रमाण-पत्र प्राप्त करने का अधिकार नहीं है। एक नया जीएसएस कॉन्टेक्स्ट बनाने और इसे आरंभ करने के लिए यहां क्या लापता है। इस विधि से वापसी मूल्य में सेवा टिकट होता है, अगर मैं इसे सही ढंग से समझ गया हूं। यहां एक कामकाजी कोड उदाहरण है। यह एक विषय में लॉग इन की ओर से एक PrivilegedAction में चला जाना चाहिए:

GSSManager manager = GSSManager.getInstance(); 
    GSSName clientName = manager.createName("clientUser", GSSName.NT_USER_NAME); 
    GSSCredential clientCred = manager.createCredential(clientName, 
                 8 * 3600, 
                 createKerberosOid(), 
                 GSSCredential.INITIATE_ONLY); 

    GSSName serverName = manager.createName("[email protected]", GSSName.NT_HOSTBASED_SERVICE); 

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

    byte[] outToken = context.initSecContext(new byte[0], 0, 0); 
    System.out.println(new BASE64Encoder().encode(outToken)); 
    context.dispose(); 

outToken तो शामिल सेवा टिकट शामिल हैं। हालांकि जीएसएस-एपीआई का इस्तेमाल करने का यह तरीका नहीं था। इसका लक्ष्य कोड को उन विवरणों को छिपाना था, इसलिए दोनों पक्षों पर जीएसएस-एपीआई का उपयोग करके जीएसएस कॉन्टेक्स्ट स्थापित करना बेहतर है। अन्यथा आपको वास्तव में पता होना चाहिए कि आप संभावित सुरक्षा छेद के कारण क्या कर रहे हैं। अधिक जानकारी के लिए मैंने देखा है कि Sun SSO tutorial with kerberos अधिक सावधानी से पढ़ें।

संपादित करें: बस भूल गया कि मैं SP2 के साथ Windows XP का उपयोग कर रहा हूं। विंडोज़ के इस संस्करण में एक नई "फीचर" है जो विंडोज रैम में टीजीटी का उपयोग करने से मना करती है। इसे अनुमति देने के लिए आपको रजिस्ट्री को संपादित करना होगा। अधिक जानकारी के लिए JGSS Troubleshooting page विषय पर एक नज़र डालें, यदि आपको "KrbException: KDC का एन्क्रिप्शन प्रकार (14)" के लिए कोई समर्थन नहीं है जैसा मैंने किया था।

+0

@ माइकल: आपके योगदान के लिए धन्यवाद। जैसा कि आप देख सकते हैं मैंने इसे कुछ समय पहले लिखा था इसलिए मुझे सटीक विवरण याद नहीं हैं, लेकिन मुझे पूरा यकीन है कि यह सिर्फ एक उदाहरण के रूप में था। इस जवाब को बेहतर बनाने के लिए आपको क्या लगता है? –

+0

केर्बेरोस के साथ सूर्य एसएसओ ट्यूटोरियल के लिए अपने लिंक की जांच करें और आंकड़े 6 पर एक नज़र डालें। मैंने जिस लूप को लिखा है वह है। –

+0

मुझे लगता है कि मैंने लूप को शामिल नहीं किया क्योंकि मुझे पता नहीं चला कि readToken() और sendToken (...) विधियों को क्या करना चाहिए। HTTP 'readToken' के संदर्भ में –

7

मुझे इस कोड का उपयोग करने में बहुत सारी समस्याएं थीं, लेकिन मेरे पास कम से कम एक समाधान है। मैं इसे यहां पोस्ट करता हूं, शायद यह आप में से कुछ की मदद करेगा ...

/** 
* 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()); 
     lc.login(); 

     // 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("MYFIRM.COM", "kerbserver", "HTTP/webserver.myfirm.com"); 
     System.out.println(ticket); 
    } 
} 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^