calling soap service with transport base security( HTTPS) service in IOS

I created application of calling https soap service(with transport security), but i get status code of 400 with null

webdata
.


My code is:



/
- (NSString* )serviceCall{
    NSString *soapActionURL;
soapActionURL=[NSString stringWithFormat: @"http:/
    NSString *soapMessage = [NSString stringWithFormat:
                             @"<s:Envelope xmlns:s=\"http:/
                             " <s:Body>\n"
                                "<GetData xmlns=\"http:/
                                "<value>10</value>\n"
                                "</GetData>\n"
                             "</s:Body>\n"
                            "</s:Envelope>\n"];
    url = [NSURL URLWithString:@"https:/
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    NSString *msgLength = [NSString stringWithFormat:@"%lu", (unsigned long)[soapMessage length]];
    NSData* bodyData = [soapMessage dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger bodyDataLength = [bodyData length];
    [theRequest setTimeoutInterval:10.0f];
    [theRequest addValue: @"application/soap+xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [theRequest addValue: soapActionURL forHTTPHeaderField:@"SOAPAction"];
    [theRequest addValue: [NSString stringWithFormat:@"%lu", (unsigned long)bodyDataLength] forHTTPHeaderField:@"Content-Length"];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setHTTPBody: bodyData];
    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    if (theConnection) {
        webData = [NSMutableData data] ;
    }
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    /
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
    NSLog(@"Status code %ld", (long)[httpResponse statusCode]);
    [webData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    /
    [webData appendData:data];
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
    NSMutableArray *list =[[NSMutableArray alloc]init];
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:webData];
    NSString *xmlData = [[NSString alloc]
                         initWithBytes:[webData mutableBytes]
                         length:[webData length]
                         encoding:NSUTF8StringEncoding];
    NSLog(xmlData);
}
/
- (BOOL) connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
/
    BOOL authResult;
    authResult= [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
    /
    if(authResult)
    {
        NSLog(@"Auth is Ok");
    }
    return authResult;
}
- (void) connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    NSLog(@"___didReceiveAuthenticationChallenge");
    if([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodServerTrust]) {
        /
        if ([challenge.protectionSpace.host isEqualToString: challenge.protectionSpace.host]) {
             NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
            NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
        }
    }
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
     NSLog(@"@%",error);
}




I get following Result:


WSServiceTest[2988:54075] Auth is Ok

WSServiceTest[2988:54075] ___didReceiveAuthenticationChallenge

WSServiceTest[2988:54075] trusting connection to host 192.168.0.10

WSServiceTest[2988:54075] Status code 400

WSServiceTest[2988:54075] (null)


Also on debug i get:


/

<NSHTTPURLResponse: 0x7fa80a78c8b0> { URL: https://192.168.0.10/Service/Service1.svc } { status code: 400, headers {
    "Content-Length" = 0;
    Date = "Thu, 18 Feb 2016 05:59:37 GMT";
    Server = "Microsoft-IIS/7.5";
    "X-Powered-By" = "ASP.NET";
} }


How can i get proper result? or what is wrong in my code?

Hmmm, lots of comments:

  • Don’t use NSURLConnection for new code. It’s recently been deprecated in favour of NSURLSession.

  • Even within NSURLConnection you’re using deprecated delegate callbacks.

    -connection:canAuthenticateAgainstProtectionSpace:
    and
    -connection:didReceiveAuthenticationChallenge:
    have long since been deprecated in favour of
    -connection:willSendRequestForAuthenticationChallenge:
    .
  • Your

    -connection:didReceiveAuthenticationChallenge:
    method is, frankly, odd. If you get a
    NSURLAuthenticationMethodServerTrust
    challenge, you end up resolving the challenge twice, once inside the
    if
    and once outside. You should only resolve a challenge once.
  • If you get a challenge that you don’t understand, resolve it using

    -performDefaultHandlingForAuthenticationChallenge:
    not
    -continueWithoutCredentialForAuthenticationChallenge:
    .
  • You can avoid the need to handle the

    NSURLAuthenticationMethodServerTrust
    authentication challenge by giving your server a proper digital identity. If you don’t want to do that during the initial bring up phase, you can use the instructions in Technote 2326 Creating Certificates for TLS Testing to generate a test identity on your Mac.
  • As to why you get a 400 status from the server, there’s two possibilities I can see:

    • It’s possible that the issues with your authentication challenging handling are causing a spurious problem with your request. So you should fix all of the above first.

    • If not, it’s hard to debug things like this on the client side because authorisation is implemented on the server side.

I recommend that you fix you challenge handling, then retest, then repost with an update if you’re still having issues.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanx @eskimo for your replay


One more thing, above code is work fine when i used it for normal http service request....

I am new to the objective-c, will you plz give me updated code...

Hello @Eskimo

When i Try to ignore ssl using willSendRequestForAuthenticationChallenge, i get NSURLCredential null

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        NSLog(@"Ignoring SSL");
        SecTrustRef trust = challenge.protectionSpace.serverTrust;
        NSURLCredential *cred;
        cred = [NSURLCredential credentialForTrust:trust];
        [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
        return;
    }
    /
}

How can i ignore authentication(SSL)?

Why are you using NSURLConnection for this?

With regards your code snippet, what’s up with line 12? Did you remove some code to post this example? If so, what?

I’d expect line 12 to look like this:

[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];

Also, have you disabled App Transport Security in your app? That provides HTTPS security checking above and beyond the standard checking done by NSURL{Session,Connection} and you’ll have to disable it if you want to connect to a server with broken HTTPS.

btw You can avoid all of this HTTPS drama by configuring your server to use test credentials. See my discussion of TN2326 above.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Actually i am trying to creating plugin for unity3d to access https soap service in my game. and for NSURLConnection, when i started working on plugin that time i used NSURLConnection so..

I sitll get satus code 400 after adding that code line at line no 12...


- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        NSLog(@"Ignoring SSL");
        SecTrustRef trust = challenge.protectionSpace.serverTrust;
        NSURLCredential *cred;
        cred = [NSURLCredential credentialForTrust:trust];
        [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
        return;
    }
    [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
}
@end

I sitll get satus code 400 after adding that code line at line no 12...

HTTP status 400 is Bad Request. This status is coming from the server. Have you look at the body of the failure response? Sometimes the server will have a short description of the badness here. If that’s not helpful, your options are:

  • Look on the server to see why it failed the request.

  • If you have a known working client, you can compare the request sent by it to the request sent by your client to see what’s different.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

When i see response i get following description:


Printing description of response:
<NSHTTPURLResponse: 0x7fb5385444e0> { URL: https://192.168.0.10/NewAndService/AndWsService.svc } { status code: 400, headers {
    "Content-Length" = 0;
    Date = "Mon, 22 Feb 2016 09:31:28 GMT";
    Server = "Microsoft-IIS/7.5";
    "X-Powered-By" = "ASP.NET";
} }


One more thing when i try to access service without https(for http) it work fine and for https service it give me above response...


Also i access that service(https) for android & windows pc it work fine, but not in ios.........

When i see response i get following description:

I was looking for the response body, but it turns out that this is sufficient (the

Content-Length
header is 0, indicating that there’s no helpful message in the response body).

One more thing when i try to access service without https(for http) it work fine and for https service it give me above response...

Right, which just reinforces that this is wackiness on the server, not the client (-:

Also i access that service(https) for android & windows pc it work fine, but not in ios.........

In which case you should compare the requests issued by both clients to see what’s different between the two. As these are protected by TLS you can’t use a simple packet trace. There are two possibilities here:

  • See if the server has a way to give you the plaintext of the request.

  • Use a proxy-based HTTPS debugging tool, like Charles (see QA1176 for a link).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

For windows & android i used following code to ignore Certification:


ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback (IgnoreCertificateErrorHandler);

//
public static bool IgnoreCertificateErrorHandler (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
  {
  return true;
  }

For windows & android i used following code to ignore Certification:

Right, but that’s not the issue you’re facing. iOS is ignoring the certificate of the server; you know that because you successfully passed a request to the server and got back a response. The HTTP status in that response, 400 Bad Request, indicates that there’s something that the server doesn’t like about your request.

There’s no way to figure out what the server is complaining about by looking at just your iOS code. You will either have to debug this on the server or compare the iOS and non-iOS requests to see what’s different about the two.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

btw I just posted some general advice for how to deal with problems like this; see Debugging HTTP Server-Side Errors.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

will you please give me reference or any example of calling soap web service using NSURLSession with ssl ignoration.....

Please..

will you please give me reference or any example of calling soap web service using NSURLSession with ssl ignoration.....

I don’t have such an example and, even if I did, it wouldn’t help you because the errors you’re getting are coming from your server.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Will you please tell me how to call web service in NSURLSession with all interface methods of NSURLSession (like NSURLConnection in above code). also tell me how to ignore SSL in NSURLSession..(any example or link)...


can we call web service with WSHttpBinding in ios? how?

calling soap service with transport base security( HTTPS) service in IOS
 
 
Q