UIWebView + Sharepoint + NTLM Auth - 我得到Stream在打开之前发送一个事件

时间:2014-10-06 19:33:04

标签: ios sharepoint ssl uiwebview ntlm

我一直在开发一个应用程序,其中包含一个显示Sharepoint站点的简单UIWebView。我原本以为NTLM身份验证会是一个问题,但事实证明这是非常直接的。但是,自iOS8以来,我的应用程序一直在发送垃圾邮件“Stream在打开之前发送一个事件”在我的日志中一遍又一遍,以至于页面真的永远无法加载。

我原本以为这是我正在做的事情所以我创建了一个小应用程序(下面)来消除我的其他应用程序可能有的任何奇怪但不幸的是我得到了同样的问题。我想我的主要问题是我不知道从哪里开始寻找这个问题的答案。互联网已经提到了这一点,但没有明确的解决方案,如[webView dontDoThat]。 :d

我正在手动添加连接到运行循环,您将在代码中看到这一点。我已经尝试了各种方式,我知道如何创建连接,但这是最近的尝试。

我开始处理SSL质询,因为我的证书对域名无效,然后我收到NTLM质询并发送硬编码用户名并作为测试传递。它部分加载了网站,但最终放弃了加载我认为是这个错误的所有资源。理论欢迎。

//
//  ViewController.m
//
//  Created by Greg Frame on 10/2/14.
//

#import "ViewController.h"

#define APPURL @"https://mysharepoint.com"
#define USERNAME @"usernamehere"
#define PASSWORD @"passwordhere"

@interface ViewController ()

@end

@implementation ViewController

BOOL _Authenticated = NO;
BOOL _SSLAuthenticated = NO;
NSURLConnection *_Connection;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.webView.delegate = self;
    NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
    [self.webView loadRequest:requestURL];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark UIWebViewDelegate
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request   navigationType:(UIWebViewNavigationType)navigationType {
    if(webView.loading){ //if url requests come through while its loading, its probably embedded content
        return YES;
    }

    BOOL result = YES;
    if (!_Authenticated || !_SSLAuthenticated) {
        //I have tried a ton of different ways to create the NSURLConnection this is the latest
        _Connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
        [_Connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
        [_Connection start];
        result = NO;
    }
    return result;
}

#pragma mark NSURLConnection Delegate
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:    (NSURLAuthenticationChallenge *)challenge {
    if( [challenge previousFailureCount] == 0 ) {
    if ([challenge.protectionSpace.authenticationMethod     isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            NSLog(@"SSL Challenge");
            NSURL* baseURL = [NSURL URLWithString:APPURL];
            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);
        } else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodNTLM]) {
            NSLog(@"NTLM Challenge");
            _SSLAuthenticated = YES;  //cant get here otherwise


            //persistence:NSURLCredentialPersistenceForSession
            NSURLCredential *cred = [NSURLCredential credentialWithUser:USERNAME password:PASSWORD persistence:NSURLCredentialPersistencePermanent];
            [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
        } else {
            NSLog(@"Unsupported Challenge");
            [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
        }
    } else {
        NSLog(@"Failed authentication");
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse {
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)pResponse;
    NSLog(@"Received response %ld", (long)[httpResponse statusCode]);

    if( !_SSLAuthenticated && [httpResponse statusCode] == 200) {    
        NSLog(@"SSL GOOD");
        _SSLAuthenticated = YES;
        [_Connection cancel];
        _Connection = nil;
        NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
        [self.webView loadRequest:requestURL];
        return;
    }

    if( !_Authenticated && [httpResponse statusCode] == 200) {
        NSLog(@"NTLM GOOD");
        _Authenticated = YES;
        [_Connection cancel];
        [_Connection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

        NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:APPURL]];
        [self.webView loadRequest:requestURL];
        return;
    }

    NSLog(@"Connection Cancelled");
    [_Connection cancel];
}

@end

免责声明:零件和碎片是从其他人复制的,因此我并不声称已经手动输入了每一行。感谢所有拥有我在此示例中提供的代码的人。

任何帮助表示赞赏! - 格雷格框架

一些日志条目:

 2014-10-06 15:12:31.110 sptest2[21405:2051411] SSL Challenge
 2014-10-06 15:12:31.110 sptest2[21405:2051411] trusting connection to host xxxxx.xxxxx.com
 2014-10-06 15:12:31.426 sptest2[21405:2051411] NTLM Challenge
 2014-10-06 15:12:31.899 sptest2[21405:2051690] Stream 0x7c8d9070 is sending an event before being opened
 2014-10-06 15:12:32.429 sptest2[21405:2051411] Received response 200
 2014-10-06 15:12:32.429 sptest2[21405:2051411] NTLM GOOD
 2014-10-06 15:12:33.184 sptest2[21405:2051723] Stream 0x7ca95210 is sending an event before being opened
 2014-10-06 15:12:34.293 sptest2[21405:2051723] Stream 0x7bed9740 is sending an event before being opened
 2014-10-06 15:12:34.465 sptest2[21405:2051723] Stream 0x7bee1120 is sending an event before being opened
 2014-10-06 15:12:34.523 sptest2[21405:2051723] Stream 0x7caba9a0 is sending an event before being opened
 2014-10-06 15:12:34.532 sptest2[21405:2051723] Stream 0x7f87e040 is sending an event before being opened
 ...

0 个答案:

没有答案