2015-09-03 2 views
1

Я пытаюсь получить доступ к json webservice, защищенному как SSL, так и NTLM из моего приложения для Android. Конечно, из браузера я могу напрямую нажать на URL https://service.example.com/service1/, пройти аутентификацию с помощью домена/пользователя/пароля и получить json-результат.Android Использование NTLM через SSL сбой

Использование JCIFS, я работаю в NTLM, я могу получить доступ к этому веб-сервису через HTTP (на тестовом устройстве в специальной сети), и все отлично работает.

Рабочий код

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

Где NTLMSchemeFactory находится от JCIFSEngine кода

Так при переключении ССЛ я обнаружил, что сервер сервиса не предоставляет промежуточные сертификаты (см https://developer.android.com/training/articles/security-ssl.html#MissingCa) и так java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. Exception бросается.

Я попытался добавить этот конкретный сертификат в диспетчер доверия, но он продолжал заставлять сервер возвращать 500 ошибок. Поэтому я даже попытался разрешить всем сертификатам, использующим пустой диспетчер доверия, даже начать с этого, и это также вызывает 500 ошибок.

Код (Родом из 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); 
} 

Использование оригинального рабочего кода, но замена DefaultHttpClient httpclient = new DefaultHttpClient(); с DefaultHttpClient httpclient = MySSLSocketFactory.getNewHttpClient();

Как я могу идти о сочетании проверки подлинности NTLM с плохим соединением SSL?

Я пытаюсь заставить пользователей сервера webservice включать их промежуточные сертификаты, но я не очень надеюсь на это прямо сейчас.

+0

Какую версию SSL вы использовали? –

+0

@IgorGanapolsky, как бы я это узнал? Это приложение все еще работает на моем современном Android-устройстве. – Aaron

+0

Запустить это из командной строки: ** openssl s_client -connect yourdomain.com:443** –

ответ

0

Таким образом, решение моей проблемы состояло в том, чтобы получить промежуточные сертификаты, загруженные на веб-сервере, предоставляя веб-сервис. Android просто не нравится или обрабатывает отсутствующие промежуточные сертификаты, подобные браузерам.