2012-03-27 24 views
5

Estoy escribiendo una conexión HTTP con autenticación Kerberos. Tengo "HTTP/1.1 401 no autorizado". ¿Me podría recomendar lo que debería verificar? Creo que hay algún truco, pero no lo veo.Conexión Kerberos utilizando el cliente HTTP

¿Debería establecer el encabezado "WWW-Authenticate" con "Negotiate"?

Muchas gracias de antemano por cualquier ayuda e ideas.

public class ClientKerberosAuthentication { 

    public static void main(String[] args) throws Exception { 

     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"); 

     DefaultHttpClient httpclient = new DefaultHttpClient(); 
     try { 
      NegotiateSchemeFactory nsf = new NegotiateSchemeFactory(); 
      httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf);    

      List<String> authpref = new ArrayList<String>(); 
      authpref.add(AuthPolicy.BASIC); 
      authpref.add(AuthPolicy.SPNEGO); 
      httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref);    


      httpclient.getCredentialsProvider().setCredentials(
        new AuthScope(null, -1, AuthScope.ANY_REALM, AuthPolicy.SPNEGO), 
        new UsernamePasswordCredentials("myuser", "mypass"));    

      System.out.println("----------------------------------------"); 
      HttpUriRequest request = new HttpGet("http://localhost:8084/web-app/webdav/213/_test.docx"); 
      HttpResponse response = httpclient.execute(request); 
      HttpEntity entity = response.getEntity(); 

      System.out.println("----------------------------------------"); 
      System.out.println(response.getStatusLine()); 
      System.out.println("----------------------------------------"); 
      if (entity != null) { 
       System.out.println(EntityUtils.toString(entity)); 
      } 
      System.out.println("----------------------------------------"); 

      // This ensures the connection gets released back to the manager 
      EntityUtils.consume(entity); 

     } finally { 
      httpclient.getConnectionManager().shutdown(); 
     } 
    } 
} 
+0

me han redactado una solución alternativa para este problema aquí: http://stackoverflow.com/a/22865583/381161 –

Respuesta

0

Tuve el mismo problema y acabo de encontrar tu publicación. Lo marqué como favorito para poder publicar una respuesta cuando lo arreglé. Publiqué un enlace a mi pregunta donde alguien respondió, por lo que si alguien encuentra esto en Google encuentra la respuesta:

HttpClient tiene problemas para crear el SPN para el AD cuando la URL tiene un puerto.

Ver mi pregunta + respuesta aquí: HttpClient check Kerberos secured webpage. NTLM login didn't work

3

SPNEGO no funcionará porque se utiliza como nombre de host localhost URL.

Su servidor está configurado para un conjunto de SPN (o al menos uno) que comienzan con HTTP/ registrados en la cuenta del servicio ActiveDirectory. Puede consultarlos desde AD gracias a setspn -l yourServiceAccount.

Su URL debe utilizar un nombre de host de servidor efectivo conocido como SPN en ActiveDirectory para que Apache Http Client pueda negociar un TGS para este servicio y enviarlo a su servidor.

0

Aquí hay un cliente de prueba que escribí en mi proyecto. Este cliente se basa en todos los tipos de cifrado esté disponible en JDK,

Si ves siguiente en sus registros y su tabla de claves se cifra en etypes por defecto de 256 bits para default_tkt_enctypes: 17 16 23 1 3.

continuación frasco siguiente http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html necesidades para ser descargado y colocado en JDK/jre/lib/security para habilitar el cifrado AES256 poco después de que usted debe ver la siguiente en los registros de etypes predeterminados para default_tkt_enctypes: 18 17 16 23 1 3.

import java.io.IOException; 
import java.io.InputStream; 
import java.security.Principal; 
import java.security.PrivilegedAction; 
import java.util.Arrays; 
import java.util.HashMap; 
import java.util.HashSet; 
import java.util.Set; 

import javax.security.auth.Subject; 
import javax.security.auth.kerberos.KerberosPrincipal; 
import javax.security.auth.login.AppConfigurationEntry; 
import javax.security.auth.login.Configuration; 
import javax.security.auth.login.LoginContext; 

import org.apache.commons.io.IOUtils; 
import org.apache.http.HttpResponse; 
import org.apache.http.auth.AuthSchemeProvider; 
import org.apache.http.auth.AuthScope; 
import org.apache.http.auth.Credentials; 
import org.apache.http.client.CookieStore; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.config.AuthSchemes; 
import org.apache.http.client.config.CookieSpecs; 
import org.apache.http.client.config.RequestConfig; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.methods.HttpUriRequest; 
import org.apache.http.config.Lookup; 
import org.apache.http.config.RegistryBuilder; 
import org.apache.http.impl.auth.SPNegoSchemeFactory; 
import org.apache.http.impl.client.BasicCookieStore; 
import org.apache.http.impl.client.BasicCredentialsProvider; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClientBuilder; 
import org.apache.http.impl.cookie.BasicClientCookie; 

clase de utilidad

public class KerberosHttpClient { 
    private String principal; 
    private String keyTabLocation; 

    public KerberosHttpClient() {} 
    public KerberosHttpClient(String principal, String keyTabLocation) { 
     super(); 
     this.principal = principal; 
     this.keyTabLocation = keyTabLocation; 
    } 

    public KerberosHttpClient(String principal, String keyTabLocation, String krb5Location) { 
     this(principal, keyTabLocation); 
     System.setProperty("java.security.krb5.conf", krb5Location); 
    } 

    public KerberosHttpClient(String principal, String keyTabLocation, boolean isDebug) { 
     this(principal, keyTabLocation); 
     if (isDebug) { 
      System.setProperty("sun.security.spnego.debug", "true"); 
      System.setProperty("sun.security.krb5.debug", "true"); 
     } 
    } 

    public KerberosHttpClient(String principal, String keyTabLocation, String krb5Location, boolean isDebug) { 
     this(principal, keyTabLocation, isDebug);   
     System.setProperty("java.security.krb5.conf", krb5Location); 
    } 

    private static HttpClient buildSpengoHttpClient() { 
     HttpClientBuilder builder = HttpClientBuilder.create();    
     Lookup<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create(). 
       register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true)).build(); 
     builder.setDefaultAuthSchemeRegistry(authSchemeRegistry); 
     BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 
     credentialsProvider.setCredentials(new AuthScope(null, -1, null), new Credentials() { 
      @Override 
      public Principal getUserPrincipal() { 
       return null; 
      } 
      @Override 
      public String getPassword() { 
       return null; 
      } 
     }); 
     builder.setDefaultCredentialsProvider(credentialsProvider);   
     CloseableHttpClient httpClient = builder.build(); 
     return httpClient; 
    } 

    public HttpResponse callRestUrl(final String url,final String userId) { 
     //keyTabLocation = keyTabLocation.substring("file://".length()); 
     System.out.println(String.format("Calling KerberosHttpClient %s %s %s",this.principal, this.keyTabLocation, url)); 
     Configuration config = new Configuration() { 
      @SuppressWarnings("serial") 
      @Override 
      public AppConfigurationEntry[] getAppConfigurationEntry(String name) { 
       return new AppConfigurationEntry[] { new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", 
         AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new HashMap<String, Object>() { 
          { 
           put("useTicketCache", "false"); 
           put("useKeyTab", "true"); 
           put("keyTab", keyTabLocation); 
           //Krb5 in GSS API needs to be refreshed so it does not throw the error 
           //Specified version of key is not available 
           put("refreshKrb5Config", "true"); 
           put("principal", principal); 
           put("storeKey", "true"); 
           put("doNotPrompt", "true"); 
           put("isInitiator", "true"); 
           put("debug", "true"); 
          } 
         }) }; 
      } 
     }; 
     Set<Principal> princ = new HashSet<Principal>(1); 
     princ.add(new KerberosPrincipal(userId)); 
     Subject sub = new Subject(false, princ, new HashSet<Object>(), new HashSet<Object>()); 
     try { 
      LoginContext lc = new LoginContext("", sub, null, config); 
      lc.login(); 
      Subject serviceSubject = lc.getSubject(); 
      return Subject.doAs(serviceSubject, new PrivilegedAction<HttpResponse>() { 
       HttpResponse httpResponse = null; 
       @Override 
       public HttpResponse run() { 
        try {  
         HttpUriRequest request = new HttpGet(url); 
         HttpClient spnegoHttpClient = buildSpengoHttpClient(); 
         httpResponse = spnegoHttpClient.execute(request); 
               return httpResponse; 
        } catch (IOException ioe) { 
         ioe.printStackTrace(); 
        } 
        return httpResponse; 
       } 
      }); 
     } catch (Exception le) { 
      le.printStackTrace();; 
     } 
     return null; 
    } 

    public static void main(String[] args) throws UnsupportedOperationException, IOException { 
     KerberosHttpClient restTest = new KerberosHttpClient("HTTP/[email protected]", 
       "file://C://Development//test.keytab", true); 
     HttpResponse response = restTest.callRestUrl("http://test.com/service/employees", 
       "HTTP/[email protected]"); 
     InputStream is = response.getEntity().getContent(); 
     System.out.println("Status code " + response.getStatusLine().getStatusCode()); 
     System.out.println(Arrays.deepToString(response.getAllHeaders())); 
     System.out.println(new String(IOUtils.toByteArray(is), "UTF-8")); 
    } 
} 
Cuestiones relacionadas