HTTPS経由でサーバーに接続する必要があるAndroidアプリケーションを作成しています。私が試した最初の解決策はこれでした:(セキュリティ上の欠陥を気にしないでください)
final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
private static void trustAllHosts() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
Log.d("USR_SSL", e.getMessage());
}
}
//...
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
//This is an HTTPS url
String jsonStr = "";
if(params.length > 1) {
jsonStr = params[1];
}
HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection();
trustAllHosts();
urlConn.setHostnameVerifier(DO_NOT_VERIFY);
urlConn.setRequestProperty("Content-Type", "application/json");
urlConn.setRequestProperty("Accept", "application/json");
urlConn.setRequestMethod("POST");
OutputStream os = urlConn.getOutputStream();
os.write(jsonStr.getBytes());
os.flush();
//...
認証、セッション、その他すべての優れた機能も使用する必要があることに気付くまでは、(ほぼ)すべてうまくいきました。以下を使用して本当に問題がなかったはずです。
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
ただし、残念ながら、Android APIレベル8をサポートする必要があります。つまり、上記の2行のコードは機能しません。それを踏まえて、私は数時間インターネットを調べて、HTTPSとCookieの両方をサポートしているように見えるApacheクラスを使用してソリューションを構築しようとしました。
これは私がなんとか一緒に縫うことができたコードです:
public class ConnectionMediator {
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) {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
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 void tryConnect(String url, String data) {
try {
//SSL Stuff
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory 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);
DefaultHttpClient httpClient = new DefaultHttpClient(ccm, params);
//Cookie stuff
HttpContext localContext = new BasicHttpContext();
HttpResponse response = null;
HttpPost httpPost = null;
StringEntity tmp = null;
httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);
httpPost = new HttpPost(url);
tmp = new StringEntity(data,"UTF-8");
httpPost.setEntity(tmp);
response = httpClient.execute(httpPost,localContext);
} catch(Exception e) {
Log.d("USR_DEBUG", e.getClass().toString() + ": " + e.getMessage());
}
}
}
これを書いている時点で、私はを取得しますNetworkOnMainThreadException
が、これはかなり重要ではありません。重要なことと私が指摘したいことは、HTTPSを使用して接続し、Cookieを使用する場合のように、自分が何をしているのかわからないということです。これまで聞いたことのない13の異なるクラスを使用する必要があります。の。明らかに、HTTPS / Javaネットクラスに関する私の知識はnullに隣接していますが、それにもかかわらず、私はもっと直感的な何かを期待していました。したがって、「これは機能しない」タイプの質問ではなく、「何をすべきか」、または「どうすれば自分がしなければならないことを学ぶことができるか」という質問になります。
どうもありがとうございます、
非常に混乱したコーダー