2013-05-27 27 views
5

私はIOSプラットフォームにAndroidアプリを移植しようとしています。私はApache Tomcatサーバーにあるサービスからデータを取得し、最近はサービスにセキュリティを追加しました。セキュリティの概要はIOSのAndroid投稿の投稿

  1. httpsの単純な要求
  2. ある場合(valid_user) - >サービスが返すデータ
  3. 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(); 
    } 
} 

これは(それがOKに取り組んでいる)の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(); 
... 

私はいくつかの方法を試みましたが、常に同じ結果を得ました。私は私が顕著だと思うのコードを追加します。

POSTリクエストが定義されている方法では
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
    NSURLCredential *credential=[NSURLCredential credentialWithUser:self.userName password:self.userpassword persistence:NSURLCredentialPersistenceForSession]; 
    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
} 

{ 
... 
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リクエストを探してきたが、どれも行われていませんあなたはより多くの情報が必要な場合に便利...

それは

あなたの助けがapreciatedされるためにお問い合わせください。

EDIT:私は以前のものではlogin.htmlフォームを取得しなかったので、willSendRequestForAuthenticationChallengeデリゲートを変更しました。

EDIT:アンドロイドからhttpクライアントセットアップコードを追加しました。データをポストするメソッドは@MTahirの答えと似ていますが、私はまだerror.htmlを取得しています。つまり、POSTメソッドが正常に動作していますが、データが正しい方法でエンコードされていないということです。

+0

私は疑問を持っています...あなたがポストリクエストを送信する必要があるか直接メソッドを取得する必要があるかどうかを指定してください...あなたはエンコードされた値を必要とします... – maheswaran

+0

@maheswaran私は一般的なデータアクセスにGETメソッドを使用します)しかし、AndroidのバージョンではPOSTを使用しているようだから、POSTメソッドはユーザー検証の要件だと思います。すべてのコミュニケーションはhttpsです。あなたが望むのであれば、Androidバージョンからhttpclient設定コードを追加できます。 –

+0

私は質問に多くの情報を追加しました。 –

答えて

3

データを投稿するコードを探しているなら、これを試してみてください。私はこれを使っています。うまくいきます。

辞書オブジェクトに送信されるデータが必要です。データはPOSTとして送信するEcodesし、応答を返す(あなたは文字列形式で結果をしたい場合に使用できる[[NSStringのはalloc]をinitWithData:dresponseエンコーディング:NSASCIIStringEncoding];データを返す)

-(NSData*) postData:(NSDictionary *) postDataDic{ 

NSData *dresponse = [[NSData alloc] init]; 

NSURL *nurl = [NSURL URLWithString:url]; 
NSDictionary *postDict = [[NSDictionary alloc] initWithDictionary:postDataDic]; 
NSData *postData = [self encodeDictionary:postDict]; 

// Create the request 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nurl]; 
[request setHTTPMethod:@"POST"]; // define the method type 
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"]; 
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
[request setHTTPBody:postData]; 

    // Peform the request 
    NSURLResponse *response; 
    NSError *error = nil; 

    dresponse = [NSURLConnection sendSynchronousRequest:request 
               returningResponse:&response 
                  error:&error]; 

return dresponse; 
} 

このメソッドは、POSTの辞書データを準備します

- (NSData*)encodeDictionary:(NSDictionary*)dictionary { 
    NSMutableArray *parts = [[NSMutableArray alloc] init]; 
    for (NSString *key in dictionary) { 
     NSString *encodedValue = [[dictionary objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
     NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
     NSString *part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue]; 
     [parts addObject:part]; 
    } 
    NSString *encodedDictionary = [parts componentsJoinedByString:@"&"]; 
    return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding]; 
} 

混乱があれば教えてください。

+0

私はあなたのコード例を使用して、私はサーバーからerror.htmlを取得します。私はそれが暗号化エラーだと思う。私はpostメソッドが正常に実行されると思いますが、ポストのデータには特定のencriptionが必要です。御時間ありがとうございます。 –

+0

あなたはウェブサービススクリプトにアクセスできますか?はいの場合は、iOSコードから受け取った値を記録してみてください。 – MTahir

+0

サービスコードへの完全なアクセス権がありません。たとえば、ServiceRealm.jar )はバイナリ形式であり、Serviceプロジェクトには含まれていません。 –