简体   繁体   中英

Android Using NTLM over SSL failing

I am trying to access a json webservice protected by both SSL and NTLM from within my android app. Of course from a browser I can directly hit the url https://service.example.com/service1/ , authenticate with a domain/user/password, and get the json result.

Using JCIFS, I have NTLM working, I can access this webservice through HTTP (on a test device on a special network) and everything works great.

Working Code

DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());
NTCredentials creds = new NTCredentials("username", "password", "", "domain");
httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
HttpHost target = new HttpHost(serviceHostname, 80, "http");
HttpContext localContext = new BasicHttpContext();
HttpGet httpget = new HttpGet("/service1");
HttpResponse response = httpclient.execute(target, httpget, localContext);
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);

Where NTLMSchemeFactory is from the JCIFSEngine code

So when switching to SSL I found that the service's server does not provide intermediate certificates (See https://developer.android.com/training/articles/security-ssl.html#MissingCa ) and so a java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. Exception is thrown.

I've tried adding that specific cert in a trust manager but It kept causing the server to return 500 errors. So I've even further tried to allow all certs using a empty trust manager to even get started on this and that throws 500 errors too.

Code (Originally from Trusting all certificates using HttpClient over HTTPS )

public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");

public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
    super(truststore);

    TrustManager tm = new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    };

    sslContext.init(null, new TrustManager[] { tm }, null);

    }

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
    return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}

@Override
public Socket createSocket() throws IOException {
    return sslContext.getSocketFactory().createSocket();
}
public static DefaultHttpClient getNewHttpClient() {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);


        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
}

Using the original working code but Replacing DefaultHttpClient httpclient = new DefaultHttpClient(); with DefaultHttpClient httpclient = MySSLSocketFactory.getNewHttpClient();

How can I go about combining NTLM authentication with a bad SSL connection?

I am trying to get the webservice server people to include their intermediate certs, but I'm not holding out much hope right now.

So the solution to my problem was to get the intermediate certs loaded on the web server providing the webservice. Android just does not like or handle missing intermediate certs like the browsers do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM