HttpUrlConnection在Android上找不到NTLM挑战

我正在尝试使用HttpUrlConnection类将我的Android应用程序连接到IIS服务器。

我的服务器需要用户进行身份validation,因此它向客户端发送以下质询:

WWW-Authenticate: Negotiate WWW-Authenticate: NTLM 

我的问题是HttpUrlConnection似乎没有解析它。 因此,getPasswordAuthentication()永远不会调用,并返回IOException“未发现身份validation质询”。

这是我的代码:

 Authenticator.setDefault(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("myUsername", "myPassword".toCharArray()); } }); URL url = new URL(myUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept-Encoding", "gzip"); conn.setRequestProperty("Accept-Charset", "UTF-8"); conn.setRequestProperty("Accept", "*/*"); conn.setRequestProperty("Connection", "close"); conn.setDoOutput(true); conn.setDoInput(true); try { conn.connect(); status_code = conn.getResponseCode(); }catch (IOException e) { ... } 

我真的开始认为HttpUrlConnection不支持NTLM挑战。 我看到一些图书馆似乎在做这项工作,但我宁愿不使用外部库。

有人可以确认是否有可能在没有外部库的情况下使HttpUrlConnection处理NTLM挑战?

我只能通过设置下面的AuthScheme和库来使它与HttpClient一起工作: http ://jcifs.samba.org/src/jcifs-krb5-1.3.17.zip。

 HttpClient httpclient = new HttpClient(httpParameters, context); NTCredentials creds = new NTCredentials(“username”, “password”, "", "dir"); httpclient.getCredentialsProvider().setCredentials( new AuthScope(context.getString(“whatever is your main URL”), -1), creds); httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory()); 

然后实现JCIFS引擎和工厂。 您可以在http://hc.apache.org/httpcomponents-client-4.2.x/ntlm.htmlfind样本

我们仍然可以使用HttpsURLConnection – 定义一个Authenticator并绕过Certvalidation(Trusting all Certs)

包com.infosec.utils;

 import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Authenticator; import java.net.CookieHandler; import java.net.CookieManager; import java.net.CookiePolicy; import java.net.PasswordAuthentication; import java.net.URL; import java.net.URLConnection; import java.security.SecureRandom; import java.security.cert.X509Certificate; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public class SSLConnect { public static void main(String[] args) throws Exception { String urlString = System.getProperty("url", "https://yourURLgoesHere:8443/test?"); CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL)); Authenticator.setDefault(new MyAuthenticator("domainname\\yourname", "yourpassword")); URL url = new URL(urlString); URLConnection urlConnection = url.openConnection(); HttpsURLConnection httpsUrlConnection = (HttpsURLConnection) urlConnection; SSLSocketFactory sslSocketFactory = createTrustAllSslSocketFactory(); httpsUrlConnection.setSSLSocketFactory(sslSocketFactory); try (InputStream inputStream = httpsUrlConnection.getInputStream()) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line = null; while ((line = reader.readLine()) != null) { // if you want to print the content System.out.println(line); } } } // Trust any Server that provides the SSL certificate by bypassing trust managers private static SSLSocketFactory createTrustAllSslSocketFactory() throws Exception { TrustManager[] byPassTrustManagers = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } public void checkClientTrusted(X509Certificate[] chain, String authType) { } public void checkServerTrusted(X509Certificate[] chain, String authType) { } } }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, byPassTrustManagers, new SecureRandom()); return sslContext.getSocketFactory(); } } // Authenticator which intercepts and provide required credential class MyAuthenticator extends Authenticator { private String httpUsername; private String httpPassword; public MyAuthenticator(String httpUsername, String httpPassword) { this.httpUsername = httpUsername; this.httpPassword = httpPassword; } @Override protected PasswordAuthentication getPasswordAuthentication() { System.out.println("Scheme:" + getRequestingScheme()); return new PasswordAuthentication(httpUsername, httpPassword.toCharArray()); } } 

HttpUrlConnection使用http://jcifs.samba.org/与NTLM一起工作。库只需要一些小的调整,比如删除你不需要的smb java代码并修复检索responseCode。