2015-10-06 3 views
3

Есть ли способ реализовать аутентификацию NTLM с помощью HttpURLConnection? В настоящее время я реализовал его с помощью DefaultHttpClient и JCIFSEngine для схемы аутентификации. (Мое вдохновение было: Android: NTLM Authentication, ksoap, and persistent connections)NTLM аутентификация с HttpURLConnection

Но так как Android 6 Apache HTTP Client Удаление, я искал решение, помимо добавления useLibrary 'org.apache.http.legacy' в приложение Gradle файл, потому что я хочу улучшить свой код, используя HttpURLConnection класс вместо этого. Как сказано в документации, этот API более эффективен, поскольку он снижает использование сети благодаря прозрачному кешированию сжатия и ответа и минимизирует энергопотребление.

+0

Вы посмотрели на OkHTTP и Модернизацию? – Smashing

+0

Нет, я посмотрю и посмотрю, подходят ли они моему делу. –

ответ

4

HttpURLConnection может работать с NTLM, только если вы добавите библиотеку jcifs.

Этот пример работает с последними jcifs-1.3.18:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.net.UnknownHostException; 
import java.util.HashMap; 
import java.util.Map; 

import org.apache.http.impl.auth.NTLMEngineException; 

public class TestNTLMConnection { 
    public static void main(String[] args) throws UnknownHostException, IOException, NTLMEngineException { 
     // Method 1 : authentication in URL 
     jcifs.Config.registerSmbURLHandler(); 
     URL urlRequest = new URL("http://domain%5Cuser:[email protected]/"); 

     // or Method 2 : authentication via System.setProperty() 
     // System.setProperty("http.auth.ntlm.domain", "domain"); 
     // System.setProperty("jcifs.smb.client.domain", "domain"); 
     // System.setProperty("jcifs.smb.client.username", "user"); 
     // System.setProperty("jcifs.smb.client.password", "pass"); 
     // Not verified // System.setProperty("jcifs.netbios.hostname", "host"); 
     // System.setProperty("java.protocol.handler.pkgs", "jcifs"); 
     // URL urlRequest = new URL("http://127.0.0.1:8180/simulate_get.php"); 

     HttpURLConnection conn = (HttpURLConnection) urlRequest.openConnection(); 

     StringBuilder response = new StringBuilder(); 

     try { 
      InputStream stream = conn.getInputStream(); 
      BufferedReader in = new BufferedReader(new InputStreamReader(stream)); 

      String str = ""; 
      while ((str = in.readLine()) != null) { 
       response.append(str); 
      } 
      in.close(); 

      System.out.println(response); 
     } catch(IOException err) { 
      System.out.println(err); 
     } finally { 
      Map<String, String> msgResponse = new HashMap<String, String>(); 

      for (int i = 0;; i++) { 
       String headerName = conn.getHeaderFieldKey(i); 
       String headerValue = conn.getHeaderField(i); 
       if (headerName == null && headerValue == null) { 
        break; 
       } 
       msgResponse.put(headerName == null ? "Method" : headerName, headerValue); 
      } 

      System.out.println(msgResponse); 
     } 
    } 
} 

Предупреждение: JCIFS игнорирует connectTimeout и readTimeout вы определяете с библиотекой, это причина, почему соединение принимает возрастов, чтобы сломаться, когда хозяин не отвечает. Используйте код, который я описываю в this SO thread, чтобы избежать этой ошибки.

+1

Очень хорошо. Работает как шарм. –

Смежные вопросы