Android アプリを IOS プラットフォームに移植しようとしています。Apache Tomcat サーバーにあるサービスからデータを取得していますが、最近サービスにセキュリティが追加されました。セキュリティの概要は次のとおりです。
- https 簡単なリクエスト
- if(valid_user)->サービスがデータを返す
- else->サービスがログインフォームを返す->認証情報を投稿->サービスがデータを返す
Android版は問題なく動作します。セキュリティが追加される前は単純な http リクエストを実行していましたが、今では資格情報を使用して POST リクエストを実行する必要があり、結果として常に error.html を受け取ります。私はネットワーク プログラミングの専門家にはほど遠いです。
これは、Android http クライアントのセットアップ コードです。
if(httpClient==null)
{
DefaultHttpClient client = new DefaultHttpClient();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", sf, 8443));
mgr = new ThreadSafeClientConnManager(client.getParams(), registry);
int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(client.getParams(), timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 7000;
HttpConnectionParams.setSoTimeout(client.getParams(), timeoutSocket);
httpClient = new DefaultHttpClient(mgr, client.getParams());
}
そして、これは MySSLSocketFactory クラスです:
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 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();
}
}
これは Android の POST リクエスト コードです (正常に動作しています)。
...
HttpPost httpost = new HttpPost(host+"/serviceName/j_security_check");
List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
nvps.add(new BasicNameValuePair("j_username", userName));
nvps.add(new BasicNameValuePair("j_password", userPassword));
try {
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
}
catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
httpResponse = httpClient.execute(httpost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
entity = httpResponse.getEntity();
...
私はいくつかの方法を試しましたが、常に同じ結果になりました。注目に値すると思うコードのみを追加します。
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSURLCredential *credential=[NSURLCredential credentialWithUser:self.userName password:self.userpassword persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
POST リクエストが定義されているメソッド内:
{
...
NSString *urlstr=[NSString stringWithFormat:@"%@%@",host,@"serviceName/j_security_check"];
NSURL *url=[[NSURL alloc]initWithString:urlstr];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
NSString *params=[[NSString alloc]initWithFormat:@"j_username=my_userName&j_userpassword=my_userPassword"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
[[NSURLConnection alloc]initWithRequest:request delegate:self];
}
ウェブ上で有効な POST リクエストを探していましたが、どれも役に立ちませんでした...
さらに情報が必要な場合は、お尋ねください
あなたの助けに感謝します。
編集: 前のものでは login.html フォームを取得できないため、willSendRequestForAuthenticationChallenge デリゲートを変更しました。
編集: Android から http クライアント セットアップ コードを追加しました。データを投稿するメソッドは@MTahirの回答に似ていますが、まだerror.htmlが表示されます.