且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

iOS 9 ATS 使用自签名证书阻止对服务器的 HTTPS 请求

更新时间:2023-09-25 09:33:58

解决方案.谢谢大家在评论中指出我正确的方向.解决方案是创建一个 NSObject 来处理这种特殊情况的 NSURLRequests.

Solution. Thank you everybody in the comments for pointing me in the right direction. The solution was to create an NSObject that handled NSURLRequests for this special case.

归功于:https://www.cocoanetics.com/2010/12/nsurlconnection-with-self-signed-certificates/

以下内容几乎是链接中教程的直接副本,但我认为留在这里会更容易.

The following is almost a direct copy from the tutorial in the link, but I figured it'd be easier to stay here.

所以,

我必须使用以下代码创建一个新的 NSObject 类:

I had to create a new NSObject class with the following code:

BWWebService.h

BWWebService.h

#import <Foundation/Foundation.h>

@interface BWWebService : NSObject{
    NSMutableData *receivedData;
    NSURLConnection *connection;
    NSStringEncoding encoding;
}

- (id)initWithURL:(NSURL *)url;

@end

BWWebService.m

BWWebService.m

#import "BWWebService.h"

@implementation BWWebService

- (id)initWithURL:(NSURL *)url{
    if (self = [super init]){
        NSURLRequest * request = [NSURLRequest requestWithURL:url];

        connection = [NSURLConnection connectionWithRequest:request delegate:self];

        [connection start];
    }

    return self;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    // Every response could mean a redirect
    receivedData = nil;

    CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)
                                                                               [response textEncodingName]);
encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding);
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    if (!receivedData){
        // No store yet, make one
        receivedData = [[NSMutableData alloc] initWithData:data];
    }else{
        // Append to previous chunks
        [receivedData appendData:data];
    }
}

// All worked
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    NSString * xml = [[NSString alloc] initWithData:receivedData encoding:encoding];
    NSLog(@"%@", xml);
}

// And error occurred
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
     NSLog(@"Error retrieving data, %@", [error localizedDescription]);
}

// To deal with self-signed certificates
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace{
    return [protectionSpace.authenticationMethod
        isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
        // we only trust our own domain
        if ([challenge.protectionSpace.host isEqualToString:@"myuntrusteddomain.me"]){
           NSURLCredential * credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
        }
    }

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
@end

如果这还不够,为了提出请求,我使用以下内容代替了我的原始请求:

And if that wasn't enough, to make the request I used the following in replacement of my original request:

NSURL * url = [NSURL URLWithString:@"https://myuntrusteddomain.me:443/path/to/script.php"];
BWWebService * webService;
webService = [[BWWebService alloc] initWithURL:url];

我知道这不会像原始数据那样 POST 数据,但稍后会出现.我确定这将是处理 initWithURL 中的 POST 的问题.

I know that this does not POST data like the original, but that comes later. I am sure it will be a matter of handling the POST in initWithURL.

谢谢大家.

看来该解决方案的此应用程序仅适用于将允许任意负载"设置为是"的情况.

It appears this application of the solution only works with Allows Arbitrary Loads set to YES.