【问题标题】:Can't Receive JSON Request Via HTTPS Due To Untrusted Certificate由于证书不受信任,无法通过 HTTPS 接收 JSON 请求
【发布时间】:2013-10-24 01:10:11
【问题描述】:

我已经在谷歌上搜索了几个小时,但似乎找不到解决方案。

我学习的最后一个教程是 this tutorial,解释了如何通过不受信任的 SSL 连接(在本例中为自签名证书)发送 JSON 请求。

简而言之,到目前为止我尝试过的代码是这样的:

此方法检查令牌是否对我的 Web API 有效:

-(BOOL)linked
{
    if([self token] == nil)
    {
        return NO;
    }else
    {
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?token=%@&object=User&action=check_authorized", SPAtajosApiLink, [self token], nil]];
        NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
        [req setHTTPMethod:@"POST"];
        NSLog(@"%@", req);
        [req setHTTPBody: [mandatoryParameters dataUsingEncoding: NSUTF8StringEncoding]];

        NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
        [connection start];

        NSDictionary *validity = [NSJSONSerialization
                                  JSONObjectWithData:[NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]
                                  options:NSJSONReadingMutableContainers
                                  error:nil];
        NSLog(@"RESPONSE LINKED %@ %@", validity[@"code"], validity[@"message"]);
    }
    return YES;
}

我已经实现了 NSURLConnectionDelegate 方法如下:

- (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])
    {
        NSLog(@"API LINK %@", challenge.protectionSpace.host);
        if ([challenge.protectionSpace.host isEqualToString:SPAtajosApiLink])
        {
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
        }
    }

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

然而,我的应用程序总是崩溃并显示以下消息:

2013-10-15 22:48:55.382 Atajos[733:60b] { 网址: https://MY_API_URL/www/?token=657fd6c02b3ba439e69b060f7f7680cc&object=User&action=check_authorized } 2013-10-15 22:48:58.045 阿塔霍斯[733:3b17] NSURLConnection/CFURLConnection HTTP 加载失败 (kCFStreamErrorDomainSSL,-9813)2013-10-15 22:48:58.049 Atajos[733:60b] * 由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'数据参数为零' * 第一次抛出调用栈:(0x2ec2de8b 0x38f286c7 0x2ec2ddcd 0x2f5b5d77 0x5df9d 0x62395 0x31433025 0x3141e631 0x313b8be7 0x313b7edd 0x3141dca1 0x3389976d 0x33899357 0x2ebf877f 0x2ebf871b 0x2ebf6ee7 0x2eb61541 0x2eb61323 0x3141cf43 0x314181e5 0x62191 0x39421ab7) libc++abi.dylib:以未捕获的类型异常终止 NSException

好的,那么NSData,想必NSJSONSerialization中的参数是NULL。问题,为什么?

奇怪的是,我有一个类似的代码,它实际上与 UIWebView 通过不受信任的 SSL 与网站交互:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    //Need to rebuild base URL. Otherwise I get the parameters which will always fail the check.
    NSURL *requestUrl = [request URL];
    NSString *basicPathString = [NSString stringWithFormat:@"%@://%@:%@%@", requestUrl.scheme, requestUrl.host, requestUrl.port, requestUrl.path];
    NSLog(@"%@", basicPathString);

    if([basicPathString isEqualToString:SPAtajosLoginLink])
    {

        __block NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:request.URL.absoluteURL]
                                                                             options:NSJSONReadingMutableContainers
                                                                               error:nil];
        NSLog(@"Auth token is %@", jsonResponse[@"token"]);
        [self dismissViewControllerAnimated:YES completion:^{
            if([jsonResponse[@"code"] isEqualToNumber:[NSNumber numberWithInt:200]])
            {
                [[PDKeychainBindings sharedKeychainBindings] setObject:jsonResponse[@"token"]
                                                                forKey:@"com.shortcutpublicity.ios.atajos.userAccessToken"];
            }else
            {
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"No Se Pudo Autenticar", @"Error 500 title")
                message:NSLocalizedString(@"Se ha producido un error interno del servidor (500). Por favor, trata de nuevo más tarde.", @"Error describing error 500")
                delegate:nil
                cancelButtonTitle:NSLocalizedString(@"Aceptar", @"Accept") otherButtonTitles:nil];
                [alertView show];
            }
         }];
    }else {
    //--------------THIS IS THE RELEVANT PART------------
        BOOL result = _Authenticated;
        if (!_Authenticated)
        {
            _FailedRequest = request;
            NSURLConnection *trash = [[NSURLConnection alloc] initWithRequest:request delegate:self];
            if(trash)
            {
                NSLog(@"Allocated succesfully.");
            }
        }
        return result;
    }
    return YES;
}

-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSURL* baseURL = [NSURL URLWithString:SPatajosAuthLink];
        if ([challenge.protectionSpace.host isEqualToString:baseURL.host]) {
            NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
        } else
            NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);
    }
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse {
    _Authenticated = YES;
    [connection cancel];
    [_webView loadRequest:_FailedRequest];
}

我已尝试调整此代码以与 WebView 一起使用,但我没有任何运气将其与 NSURLConnection 一起使用。

说实话,我不太知道我知道这些变通办法是如何工作的。我一直在窃取并试图修改其他人的代码,但无济于事。我查看了 NSURLConnection 和 NSURLRequest 文档,但无法解决这些问题。请帮帮我。

【问题讨论】:

  • 您是否在委托方法中设置断点以确保它们被调用?
  • 无论出于何种原因,委托方法都没有被调用...好吧,让我们继续调试。
  • 您没有正确使用NSURLConnection 委托方法!也就是说,您设置了一个委托方法 - 但随后调用了同步方便的类方法。这完全没有意义。此外,您应该知道您忽略了服务器信任验证。这仅适用于测试。

标签: iphone ios ios5 nsurlconnection nsurlrequest


【解决方案1】:

我们在#ifed 块中使用此类别进行测试...确保不要将其留在生产中:

#ifdef DEBUG
@interface NSURLRequest (IgnoreSSL)
   +(BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
@end
@implementation NSURLRequest (IgnoreSSL)
   +(BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host {return YES;}
@end
#endif

【讨论】:

    【解决方案2】:
    try this Delegate method    
    
    
    
    
     - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
        {
    
    
    
            //    SecTrustRef trustRef = [[challenge protectionSpace] serverTrust];
            //    SecTrustEvaluate(trustRef, NULL);
            //
            //    SecCertificateRef certRef = SecTrustGetCertificateAtIndex(trustRef, 0);
            //
            //    NSData *certificateData = (__bridge NSData *) SecCertificateCopyData(certRef);
            //    NSLog(@"Subject: %@", [[NSString alloc] initWithData:certificateData encoding:NSUTF8StringEncoding]);
    
            // [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
    
    
            SecTrustRef trust = challenge.protectionSpace.serverTrust;
            NSURLCredential *cred;
            cred = [NSURLCredential credentialForTrust:trust];
            [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
    
    
    
        }
    

    【讨论】:

      猜你喜欢
      • 2020-10-21
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 1970-01-01
      • 2015-05-12
      相关资源
      最近更新 更多