OStack程序员社区-中国程序员成长平台

标题: ios - NSURLConnection 和 NSMutableURLRequest 身份验证 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 21:58
标题: ios - NSURLConnection 和 NSMutableURLRequest 身份验证

我有一个 iOS 应用程序,它将向网站提交用户名和密码,并检索按“登录”后加载的网页的 HTML 代码:https://grades.bsd405.org/Pinnacle/Gradebook/Logon.aspx ?.

表单数据字段如下:

__LASTFOCUS, __EVENTTARGET, __EVENTARGUMENT, __VIEWSTATE, __EVENTVALIDATION, ctl00$ContentPlaceHolder$Username, ctl00$ContentPlaceHolder$Password, ctl00$ContentPlaceHolder$lstDomains, ctl00$ContentPlaceHolder$LogonButton, PageUniqueId

这是我目前的代码:

NSURL * url = [NSURL URLWithString"https://grades.bsd405.org/Pinnacle/Gradebook/Logon.aspx?ReturnUrl=%2fPinnacle%2fGradebook%2fDefault.aspx "];

NSString *post = @"__LASTFOCUS&__EVENTTARGET&__EVENTARGUMENT&__VIEWSTATE=/wEPDwUJNTkxNzI3MDIzD2QWAmYPZBYCAgMPZBYGAgEPZBYCAgkPZBYCAgEPZBYIAgMPFgIeB1Zpc2libGVoZAIFDxYCHwBoZAIHDxYCHwBoZAIJDxYCHgVzdHlsZQUjdmVydGljYWwtYWxpZ246bWlkZGxlO2Rpc3BsYXk6bm9uZTtkAgMPDxYCHwBoZGQCBQ9kFghmD2QWAgINDxYCHgVjbGFzcwUQc2luZ2xlU2Nob29sTGlzdBYCAgEPZBYCAgEPEGQPFgFmFgEQBQ5EZWZhdWx0IERvbWFpbgUIUGlubmFjbGVnZGQCAg9kFgICEw9kFgICAQ9kFgICAQ8QZGQWAGQCBw8PFgIeBFRleHQFIFBpbm5hY2xlIEdyYWRlIDIwMTIgV2ludGVyIEJyZWFrZGQCCA8PFgIfAwU3Q29weXJpZ2h0IChjKSAyMDEzIEdsb2JhbFNjaG9sYXIuICBBbGwgcmlnaHRzIHJlc2VydmVkLmRkZP/l6irI9peZfyqpKjk3fwLuEbos&__EVENTVALIDATION=/wEWBgKjnbqUCQLnksmgAQKTpbWbDgLB5+KIBAL4xb20BAK20ZqiCel6sQLBsF1W3XHOxpgq+tJj+Rx2&ctl00$ContentPlaceHolder$Username=TESTUSERNAME&ctl00$ContentPlaceHolder$Password=TESTPASSWORD&ctl00$ContentPlaceHolder$lstDomains=Pinnacle&ctl00$ContentPlaceHolder$LogonButton=Signin&ageUniqueId=2dacba26-bb0d-412f-b06a-e02caf039c4b";

NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

NSString *postLength = [NSString stringWithFormat"%d", [postData length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

[self clearCookiesForURL:url];
[request setURL:url];

[request setHTTPMethod"OST"];
[request setValue:postLength forHTTPHeaderField"Content-Length"];
[request setValue"application/x-www-form-urlencoded" forHTTPHeaderField"Content-Type"];
[request setHTTPBody:postData];

NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];

但是,总是返回错误页面。我究竟做错了什么? 我还实现了以下内容:

-(void)connectionNSURLConnection *)connection didReceiveAuthenticationChallengeNSURLAuthenticationChallenge *)challenge {
NSLog(@"HEREEE");
if ([challenge previousFailureCount] == 0) {
    NSLog(@"received authentication challenge");
    NSURLCredential *newCredential = [NSURLCredential credentialWithUser"USERNAME"
                                                                password"ASSWORD"
                                                             persistence:NSURLCredentialPersistenceForSession];
    NSLog(@"credential created");
    [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
    NSLog(@"responded to authentication challenge");
}
else {
    NSLog(@"previous authentication failure");
}

}

但是这个方法永远不会被调用!

我的 View Controller 符合:
NSURLConnectionDelegate,NSURLAuthenticationChallengeSender,NSURLConnectionDataDelegate

谢谢!



Best Answer-推荐答案


一些想法:

  1. 我对 __VIEWSTATE__EVENTVALIDATION 中存在保留字符感到惊讶。根据 the x-www-form-urlencoded spec , 你应该使用百分比转义字符而不是 *, -, ., 0-9A-Z_a-z

    POST 值的标准百分比转义例程是:

    - (NSString *)percentEscapeStringNSString *)string
    { 
        NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                     (CFStringRef)string,
                                                                                     (CFStringRef)@" ",
                                                                                     (CFStringRef)@":/?@!$&'()*+,;=",
                                                                                     kCFStringEncodingUTF8));
        return [result stringByReplacingOccurrencesOfString" " withString"+"];
    }
    
  2. 我不确定这是否严重,但您缺少 = 个字符。所以,我希望 __LASTFOCUS=&... 而不是 __LASTFOCUS&...

    将这两点放在一起,生成的有效负载应该如下所示:

    __LASTFOCUS=&__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUJNTkxNzI3MDIzD2QWAmYPZBYCAgMPZBYGAgEPZBYCAgkPZBYCAgEPZBYIAgMPFgIeB1Zpc2libGVoZAIFDxYCHwBoZAIHDxYCHwBoZAIJDxYCHgVzdHlsZQUjdmVydGljYWwtYWxpZ246bWlkZGxlO2Rpc3BsYXk6bm9uZTtkAgMPDxYCHwBoZGQCBQ9kFghmD2QWAgINDxYCHgVjbGFzcwUQc2luZ2xlU2Nob29sTGlzdBYCAgEPZBYCAgEPEGQPFgFmFgEQBQ5EZWZhdWx0IERvbWFpbgUIUGlubmFjbGVnZGQCAg9kFgICEw9kFgICAQ9kFgICAQ8QZGQWAGQCBw8PFgIeBFRleHQFIFBpbm5hY2xlIEdyYWRlIDIwMTIgV2ludGVyIEJyZWFrZGQCCA8PFgIfAwU3Q29weXJpZ2h0IChjKSAyMDEzIEdsb2JhbFNjaG9sYXIuICBBbGwgcmlnaHRzIHJlc2VydmVkLmRkZP%2Fl6irI9peZfyqpKjk3fwLuEbos&__EVENTVALIDATION=%2FwEWBgKjnbqUCQLnksmgAQKTpbWbDgLB5%2BKIBAL4xb20BAK20ZqiCel6sQLBsF1W3XHOxpgq%2BtJj%2BRx2&ctl00%24ContentPlaceHolder%24Username=a&ctl00%24ContentPlaceHolder%24Password=b&ctl00%24ContentPlaceHolder%24lstDomains=Pinnacle&ctl00%24ContentPlaceHolder%24LogonButton=Sign+in&PageUniqueId =a3113b01-cf2f-4081-8a1a-d8557e7347de
    

    请注意整个请求正文中出现的百分比转义。我通过查看 Charles 中的请求确定了正文.

  3. 我很惊讶地看到 __VIEWSTATE__EVENTVALIDATIONPageUniqueId 是这样硬编码的。我可以很容易地想象,对这些变量使用固定值会有问题。这完全取决于网站的编程方式。我收集到您正在尝试以编程方式访问不是 Web 服务而是 HTML 界面的网站,这可能会出现问题。

    在尝试登录之前,您可能必须先使用 Logins.aspx 执行 GET 请求,然后从初始登录 HTML 中解析这些值。在尝试以编程方式与 Web 服务器交互时,您必须小心调用 Web 浏览器会调用的所有页面,因为您的应用也应该使用这样的服务器状态变量。

  4. 不相关,但您不需要指定 Content-length,因为 NSURLConnection 会根据您的 大小为您提供>httpBody.

  5. 如果您使用 didReceiveAuthenticationChallenge,请注意您应确保 else 子句调用 cancelAuthenticationChallengecontinueWithoutCredentialForAuthenticationChallenge。您总是必须调用这三种挑战方法之一。

    话虽如此,但根本不清楚 didReceiveAuthenticationChallenge 是否会被调用。您的服务器可能正在使用一些不基于质询的服务器应用级身份验证。

归根结底,我们很难根据迄今为止提供的信息来诊断问题的根源。我会联系HTML界面的作者,询问认证过程的细节。

关于ios - NSURLConnection 和 NSMutableURLRequest 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23398368/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4