Я только что решил это - Parse SDK для Android не поставляется с готовой поддержкой самоподписанных сертификатов. Вам нужно изменить код самостоятельно.
Первый шаг. Соответствующий фрагмент кода находится в ParseHttpClient.
public static ParseHttpClient createClient(int socketOperationTimeout,
SSLSessionCache sslSessionCache) {
String httpClientLibraryName;
ParseHttpClient httpClient;
if (hasOkHttpOnClasspath()) {
httpClientLibraryName = OKHTTP_NAME;
httpClient = new ParseOkHttpClient(socketOperationTimeout, sslSessionCache);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
httpClientLibraryName = URLCONNECTION_NAME;
httpClient = new ParseURLConnectionHttpClient(socketOperationTimeout, sslSessionCache);
} else {
httpClientLibraryName = APACHE_HTTPCLIENT_NAME;
httpClient = new ParseApacheHttpClient(socketOperationTimeout, sslSessionCache);
}
PLog.i(TAG, "Using " + httpClientLibraryName + " library for networking communication.");
return httpClient; }
Если ваша целевая поддержка предназначена для более продвинутой версии, чем KITKAT, вам нужно добавить в конструктор ParseURLConnectionHttpClient:
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
public boolean verify(String hostname, SSLSession session) {
if(hostname.equals("YOUR TARGET SERVER")) {
return true;
}
return false;
}});
В остальных случаях (более старые версии) код будет падать на апач, работать с ним у меня не получилось - поэтому сделал следующее: добавил в приложение библиотеку okhttp (возьмем версию 2.4 - тот же самый парс указывает в файле build , самый последний имеет другое имя пакета), а затем код перейдет к первому условию, так как он найдет okhttp в пути. Вероятно, вам следует заменить порядок условий if, чтобы это происходило только в версиях меньше, чем KITKAT.
В ParseOkHttpClient добавьте следующий код самоподписанного сертификата:
public void initCert() {
try {
Log.i("PARSE","initCert");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
String yairCert = "-----BEGIN CERTIFICATE-----\n" +
YOUR CERTIFICATE HERE
"-----END CERTIFICATE-----\n";
InputStream caInput = new ByteArrayInputStream(yairCert.getBytes());
Certificate ca = null;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} catch (CertificateException e) {
e.printStackTrace();
} finally {
try {
caInput.close();
} catch (IOException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
}
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
Log.i("PARSE","Initiating Self Signed cert");
okHttpClient.setSslSocketFactory(context.getSocketFactory());
try {
cf = CertificateFactory.getInstance("X.509");
} catch (CertificateException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
}
} catch (IOException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
} catch (CertificateException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
} catch (KeyStoreException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
} catch (KeyManagementException e) {
Log.e("PARSE_BUG","Failure on Cert installing",e);
e.printStackTrace();
}
И последняя часть — это вызов этого метода + проверка имени хоста, это тоже должно происходить в Конструкторе. инитцерт(); okHttpClient.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { if(s.equals("ВАШ ЦЕЛЕВОЙ СЕРВЕР")) { return true; } return false; } });
Вот и все. Соберите PARSE локально и разверните его в своем приложении, и он будет работать как шарм.
Наслаждаться
person
Croc
schedule
11.07.2016