如何在httpclient中为代理服务器指定kerberos身份验证

时间:2012-11-01 05:46:33

标签: proxy httpclient kerberos

我需要使用HttpClient 4.1通过Squid代理服务器与Web服务器通信。 Squid代理服务器具有与Active Directory集成的kerberos身份验证。

我无法正确配置我的Java程序以使用Squid代理服务器进行kerberos身份验证。 我收到了以下错误:

KrbException:在Kerberos数据库(7)中找不到服务器

我正在附加我在KerberosHttpClient.java和我正在使用的krb5.conf文件中进行一些修改后创建的程序。

请帮助解决问题。

以下是示例java程序

package org.apache.http.examples.client;


import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthSchemeRegistry;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.auth.NegotiateSchemeFactory;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultProxyAuthenticationHandler;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.log4j.BasicConfigurator;


public class TestKerberosHttpClient {
    private static final Log LOG = LogFactory.getLog(TestKerberosHttpClient.class);
    private static String kerbHttpHost = "http://www.google.com";

    public static void main(String[] args) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, UnrecoverableKeyException {
        BasicConfigurator.configure();
        System.setProperty("java.security.auth.login.config", "login.conf");
        System.setProperty("java.security.krb5.conf", "krb5.conf");
        System.setProperty("sun.security.krb5.debug", "true");
        System.setProperty("javax.security.auth.useSubjectCredsOnly","false");

        if( args.length > 0 )
            kerbHttpHost = args[0];

        /*      Below is helpful on windows.

         Solution 2: You need to update the Windows registry to disable this new feature. The registry key allowtgtsessionkey should be added--and set correctly--to allow session keys to be sent in the Kerberos Ticket-Granting Ticket.

         On the Windows Server 2003 and Windows 2000 SP4, here is the required registry setting:

             HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
             Value Name: allowtgtsessionkey
             Value Type: REG_DWORD
             Value: 0x01 

         Here is the location of the registry setting on Windows XP SP2:

             HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\
             Value Name: allowtgtsessionkey
             Value Type: REG_DWORD
             Value: 0x01
         */

        DefaultHttpClient httpclient = new DefaultHttpClient();
        DefaultProxyAuthenticationHandler dpah = new DefaultProxyAuthenticationHandler();
        httpclient.setProxyAuthenticationHandler(dpah);

        HttpHost host = new HttpHost("xxx.xx.xxx.xx", 3128);

        httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, host);

        httpclient.getCredentialsProvider().setCredentials(new AuthScope("xxx.xx.xxx.xx", 3128), new UsernamePasswordCredentials("qa\\Administrator", "solidcore@123"));

        AuthSchemeRegistry authSchemeRegistry = httpclient.getAuthSchemes();
        authSchemeRegistry.unregister("basic");
        authSchemeRegistry.unregister("digest");
        authSchemeRegistry.unregister("NTLM");
        authSchemeRegistry.register("Negotiate", new NegotiateSchemeFactory());
        //      authSchemeRegistry.register("NTLM", new NTLMSchemeFactory());
        //      authSchemeRegistry.register("Basic", new BasicSchemeFactory());
        httpclient.setAuthSchemes(authSchemeRegistry);


        Credentials use_jaas_creds = new Credentials() {
            @Override
            public String getPassword() {
                return null;
            }
            @Override
            public Principal getUserPrincipal() {
                return null;
            }
        };

        httpclient.getCredentialsProvider().setCredentials(
                new AuthScope(null, -1, null),
                use_jaas_creds);

        HttpUriRequest request = new HttpGet(kerbHttpHost);
        HttpResponse response = null;
        HttpEntity entity = null;

        /* note the we use the 2 parameter execute call. */
        try{
            response = httpclient.execute(request, createHttpContext(httpclient));
            String s = new BasicResponseHandler().handleResponse(response);
            System.out.println(s);
            //entity = response.getEntity();
        } catch ( Exception ex){
            LOG.debug(ex.getMessage(), ex);
        }


        System.out.println("----------------------------------------");
//      if (entity != null) {
//          System.out.println("Response content length: " + entity.getContentLength());
//          entity.writeTo(System.out);
//      }
//      if (entity != null) {
//          entity.consumeContent();
//      }
    }

    private static class MyProxyAuthHandler extends DefaultProxyAuthenticationHandler {
        @Override
        protected List<String> getAuthPreferences() {

            return super.getAuthPreferences();
        }

        @Override
        public Map<String, Header> getChallenges(HttpResponse response,
                HttpContext context) throws MalformedChallengeException {

            return super.getChallenges(response, context);
        }

        @Override
        public AuthScheme selectScheme(Map<String, Header> arg0,
                HttpResponse arg1, HttpContext arg2)
                throws AuthenticationException {
            return super.selectScheme(arg0, arg1, arg2);
        }


    }



    /**
     * createHttpContext - This is a copy of DefaultHttpClient method
     * createHttpContext with "negotiate" added to AUTH_SCHEME_PREF to allow for 
     * Kerberos authentication. Could also extend DefaultHttpClient overriding the
     * default createHttpContext.
     * 
     * @param httpclient - our Httpclient
     * @return HttpContext
     */
    static HttpContext createHttpContext(DefaultHttpClient httpclient){
        HttpContext context = new BasicHttpContext();
        context.setAttribute(
                ClientContext.AUTHSCHEME_REGISTRY, 
                httpclient.getAuthSchemes());
        context.setAttribute(
                ClientContext.AUTH_SCHEME_PREF, 
                Collections.unmodifiableList( Arrays.asList(new String[] {
                        "negotiate",
                        "ntlm",
                        "digest",
                        "basic" 
                }))
        );
        context.setAttribute(
                ClientContext.COOKIESPEC_REGISTRY, 
                httpclient.getCookieSpecs());
        context.setAttribute(
                ClientContext.COOKIE_STORE, 
                httpclient.getCookieStore());
        context.setAttribute(
                ClientContext.CREDS_PROVIDER, 
                httpclient.getCredentialsProvider());
        return context;
    }
}

以下是krb5.conf文件

[libdefaults]
    default_realm = QA.SCCM.LOCAL
    dns_lookup_kdc = true
    dns_lookup_realm = true
    ticket_lifetime = 24h
    default_keytab_name = /etc/squid3/proxy.keytab


# The following krb5.conf variables are only for MIT Kerberos.
    krb4_config = /etc/krb.conf
    krb4_realms = /etc/krb.realms
    kdc_timesync = 1
    ccache_type = 4
    #forwardable = true
    #proxiable = true

# The following encryption type specification will be used by MIT Kerberos
# if uncommented.  In general, the defaults in the MIT Kerberos code are
# correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
#
# Thie only time when you might need to uncomment these lines and change
# the enctypes is if you have local software that will break on ticket
# caches containing ticket encryption types it doesn't know about (such as
# old versions of Sun Java).

#   default_tgs_enctypes = des3-hmac-sha1
#   default_tkt_enctypes = des3-hmac-sha1
#   permitted_enctypes = des3-hmac-sha1

# The following libdefaults parameters are only for Heimdal Kerberos.
    v4_instance_resolve = false
    v4_name_convert = {
        host = {
            rcmd = host
            ftp = ftp
        }
        plain = {
            something = something-else
        }
    }
    fcc-mit-ticketflags = true

[realms]
    TESTDOMAIN1.CRM = {
        kdc = win2k3-ad1.testdomain1.crm
        admin_server = win2k3-ad1.testdomain1.crm
        default_domain = testdomain1.crm
    }
    QA.SCCM.LOCAL = {
        kdc = win-xtqhaqj5814.qa.sccm.local
        admin_server = win-xtqhaqj5814.qa.sccm.local
        default_domain = qa.sccm.local
    }
    ATHENA.MIT.EDU = {
        kdc = kerberos.mit.edu:88
        kdc = kerberos-1.mit.edu:88
        kdc = kerberos-2.mit.edu:88
        admin_server = kerberos.mit.edu
        default_domain = mit.edu
    }
    MEDIA-LAB.MIT.EDU = {
        kdc = kerberos.media.mit.edu
        admin_server = kerberos.media.mit.edu
    }
    ZONE.MIT.EDU = {
        kdc = casio.mit.edu
        kdc = seiko.mit.edu
        admin_server = casio.mit.edu
    }
    MOOF.MIT.EDU = {
        kdc = three-headed-dogcow.mit.edu:88
        kdc = three-headed-dogcow-1.mit.edu:88
        admin_server = three-headed-dogcow.mit.edu
    }
    CSAIL.MIT.EDU = {
        kdc = kerberos-1.csail.mit.edu
        kdc = kerberos-2.csail.mit.edu
        admin_server = kerberos.csail.mit.edu
        default_domain = csail.mit.edu
        krb524_server = krb524.csail.mit.edu
    }
    IHTFP.ORG = {
        kdc = kerberos.ihtfp.org
        admin_server = kerberos.ihtfp.org
    }
    GNU.ORG = {
        kdc = kerberos.gnu.org
        kdc = kerberos-2.gnu.org
        kdc = kerberos-3.gnu.org
        admin_server = kerberos.gnu.org
    }
    1TS.ORG = {
        kdc = kerberos.1ts.org
        admin_server = kerberos.1ts.org
    }
    GRATUITOUS.ORG = {
        kdc = kerberos.gratuitous.org
        admin_server = kerberos.gratuitous.org
    }
    DOOMCOM.ORG = {
        kdc = kerberos.doomcom.org
        admin_server = kerberos.doomcom.org
    }
    ANDREW.CMU.EDU = {
        kdc = vice28.fs.andrew.cmu.edu
        kdc = vice2.fs.andrew.cmu.edu
        kdc = vice11.fs.andrew.cmu.edu
        kdc = vice12.fs.andrew.cmu.edu
        admin_server = vice28.fs.andrew.cmu.edu
        default_domain = andrew.cmu.edu
    }
    CS.CMU.EDU = {
        kdc = kerberos.cs.cmu.edu
        kdc = kerberos-2.srv.cs.cmu.edu
        admin_server = kerberos.cs.cmu.edu
    }
    DEMENTIA.ORG = {
        kdc = kerberos.dementia.org
        kdc = kerberos2.dementia.org
        admin_server = kerberos.dementia.org
    }
    stanford.edu = {
        kdc = krb5auth1.stanford.edu
        kdc = krb5auth2.stanford.edu
        kdc = krb5auth3.stanford.edu
        master_kdc = krb5auth1.stanford.edu
        admin_server = krb5-admin.stanford.edu
        default_domain = stanford.edu
    }

[domain_realm]
    .testdomain1.crm = TESTDOMAIN1.CRM
    testdomain1.crm = TESTDOMAIN1.CRM
    .qa.sccm.local = QA.SCCM.LOCAL
    qa.sccm.local = QA.SCCM.LOCAL
    .mit.edu = ATHENA.MIT.EDU
    mit.edu = ATHENA.MIT.EDU
    .media.mit.edu = MEDIA-LAB.MIT.EDU
    media.mit.edu = MEDIA-LAB.MIT.EDU
    .csail.mit.edu = CSAIL.MIT.EDU
    csail.mit.edu = CSAIL.MIT.EDU
    .whoi.edu = ATHENA.MIT.EDU
    whoi.edu = ATHENA.MIT.EDU
    .stanford.edu = stanford.edu
    .slac.stanford.edu = SLAC.STANFORD.EDU

[login]
    krb4_convert = true
    krb4_get_tickets = false

0 个答案:

没有答案