2013-05-27 43 views
5

Tôi đang cố gắng chuyển một ứng dụng Android sang nền tảng iOS. Tôi nhận dữ liệu từ một dịch vụ nằm trong máy chủ Apache Tomcat và gần đây họ đã thêm bảo mật trên dịch vụ. Tổng quan về bảo mật làYêu cầu đăng Android trên IOS

  1. https đơn giản yêu cầu
  2. if (valid_user) - Dữ liệu> lợi nhuận dịch vụ
  3. else-> lợi nhuận dịch vụ vào ô đăng nhập -> bài credentials-> lợi nhuận dịch vụ dữ liệu

Phiên bản Android hoạt động mà không có vấn đề gì. Trước khi bảo mật được thêm vào, tôi đã thực hiện yêu cầu http đơn giản nhưng bây giờ tôi cần thực hiện yêu cầu POST với thông tin xác thực của mình và tôi allways nhận được error.html như là kết quả. Tôi không phải là chuyên gia về lập trình mạng.

Đây là Android mã thiết lập http client:

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

Và đây là MySSLSocketFactory lớp:

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

Đây là mã yêu cầu POST cho Android (nó đang làm việc OK):

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

Tôi đã thử một số cách nhưng tất cả đều có cùng kết quả. Tôi chỉ thêm mã mà tôi nghĩ là đáng chú ý:

-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
    NSURLCredential *credential=[NSURLCredential credentialWithUser:self.userName password:self.userpassword persistence:NSURLCredentialPersistenceForSession]; 
    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
} 

Trong phương pháp này mà yêu cầu POST được định nghĩa:

{ 
... 
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]; 
} 

Tôi đã được tìm kiếm một yêu cầu POST hợp lệ trên web nhưng không ai đã hữu ích ...

Nếu bạn cần thêm thông tin xin vui lòng yêu cầu nó

sự giúp đỡ của bạn được apreciated.

CHỈNH SỬA: Tôi đã thay đổi willSendRequestForAuthenticationThực hiện ủy quyền vì trước đó tôi không nhận được biểu mẫu login.html.

EDIT: Tôi đã thêm mã thiết lập khách hàng http từ Android. Bây giờ các phương pháp đăng dữ liệu trông giống như câu trả lời @MTahir nhưng tôi vẫn nhận được error.html, có nghĩa là (tôi nghĩ) rằng phương thức POST đang hoạt động ok nhưng dữ liệu không được viết đúng cách.

+0

tôi có một số nghi ngờ ...cho dù bạn cần gửi yêu cầu đăng bài hay phương thức nhận trực tiếp ... hãy chỉ định ... và bạn cần bất kỳ giá trị được mã hóa nào ... – maheswaran

+0

@maheswaran Tôi sử dụng phương thức GET để truy cập dữ liệu chung (bất cứ khi nào người dùng của tôi có phiên hợp lệ trên máy chủ) nhưng tôi nghĩ rằng phương thức POST là một yêu cầu trong xác thực người dùng, vì trong phiên bản Android dường như sử dụng POST. Tất cả comunication là https, nếu bạn muốn tôi có thể thêm mã cấu hình httpclient từ phiên bản Android. –

+0

Tôi đã thêm thông tin trong câu hỏi. –

Trả lời

3

Nếu bạn đang tìm một đoạn mã đang hoạt động đăng dữ liệu, hãy thử điều này, tôi đã sử dụng nó, nó hoạt động rất tốt.

Dữ liệu sẽ được gửi trong đối tượng từ điển. Ecodes dữ liệu được gửi dưới dạng POST và sau đó trả về phản ứng (nếu bạn muốn kết quả dưới dạng chuỗi bạn có thể sử dụng [[NSString alloc] initWithData: mã hóa dresponse: NSASCIIStringEncoding]; khi trở về dữ liệu)

-(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; 
} 

này phương pháp chuẩn bị dữ liệu Từ điển cho 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]; 
} 

Nếu bạn có bất kỳ sự nhầm lẫn nào, hãy cho tôi biết.

+0

Tôi đã sử dụng ví dụ mã của bạn và tôi nhận được error.html từ máy chủ. Tôi nghĩ rằng đó là một lỗi mã hóa. Tôi nghĩ rằng các phương pháp bài được thực hiện ok, nhưng các dữ liệu trong bài viết cần một số encription cụ thể. Cảm ơn vì đã dành thời gian cho tôi. –

+0

bạn có quyền truy cập vào tập lệnh dịch vụ web và nếu có, hãy thử ghi nhật ký các giá trị nhận được từ mã iOS, có thể sẽ giúp – MTahir

+0

Bây giờ tôi không có quyền truy cập đầy đủ vào mã dịch vụ, ví dụ ServiceRealm.jar (tác giả chịu trách nhiệm) ở định dạng nhị phân, nó không có trong dự án Dịch vụ. –

Các vấn đề liên quan