HttpClient 4.1 を使用して Squid Proxy Server 経由で Web サーバーと通信する必要があります。Squid Proxy Server には、Active Directory と統合された kerberos 認証があります。
Squid Proxy サーバーで kerberos 認証を行うように Java プログラムを正しく構成できません。次のエラーが表示されます:
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