How to proceed with a service URL which is untrust

2019-08-02 05:44发布

问题:

I am using a web service which is on a server with an invalid certificate but i want to get the response anyways. Is there a way to do it?? Here's the sample code:

-(void)createHttpHeaderRequest:(serviceType)type {
    NSMutableURLRequest * theRequest;
    if (type==kServiceTypeTopAccessory) {

        NSString * test = @"{\"GetVehicleInventory\": {\"ApplicationArea\": some Json object here}}}}}";

        NSString * final = (__bridge NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)test, NULL, CFSTR(":/?#[]@!$&'()*+,;=\""), kCFStringEncodingUTF8);
        NSString * sampleReq = [NSString stringWithFormat:@"https://myuntrutsedServer?XML_INPUT=%@",final];
       // NSString * final = [sampleReq stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

        NSLog(@"JSON:%@",sampleReq);


        theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:sampleReq]];
    }
    NSLog(@"Request:%@",theRequest);
    self.theConnection = [[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
    if (self.theConnection) {
        NSLog(@"Service hit");
    }
}

-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"Error%@",error);
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{

    NSLog(@"Reached here");

}

I am getting this error in my didFailWithError method : NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “209.112.58.126” which could put your confidential information at risk., NSUnderlyingError=0x6877b40 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “209.112.58.126” which could put your confidential information at risk.", NSURLErrorFailingURLPeerTrustErrorKey=}

Thanks,

回答1:

I fixed it by doing this :

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}

Enjoy!!!



回答2:

This is what I extracted from Apple's AdvancedURLConnections sample code:

if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {

    // Verify certificate:
    SecTrustResultType trustResult;
    OSStatus status = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResult);
    BOOL trusted = (status == errSecSuccess) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));

    if (trusted) {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
             forAuthenticationChallenge:challenge];
    } else {
        if (user_wants_to_trust_invalid_certificates) {
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
                 forAuthenticationChallenge:challenge];
        } else {
            [challenge.sender cancelAuthenticationChallenge:challenge];
        }
    }
} else {
    [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
}

Note: As mbm30075 correctly pointed out, this code goes into

connection:didReceiveAuthenticationChallenge:

Starting with iOS 5, you can use the delegate function

connection:willSendRequestForAuthenticationChallenge:

instead. And you have to add the Security Framework to your project to make this compile.