【发布时间】:2016-07-04 10:13:32
【问题描述】:
我的服务器提供了几种身份验证方法:NTLM 和摘要。
我的 iOS 客户端不会处理 NTLM 身份验证,因此我实现了 connection:willSendRequestForAuthenticationChallenge: 委托来拒绝 NTLM,然后仅对摘要身份验证质询使用正确的凭据。
到目前为止,在 iOS 7 上一切正常。
但在 iOS 8 上,我发现了一个奇怪的行为:connection:willSendRequestForAuthenticationChallenge: 代表在大多数时候都不会被调用(95%)!!
我得到了这个错误:
Error: Error Domain=NSPOSIXErrorDomain Code=54 "The operation couldn’t be completed. Connection reset by peer"
UserInfo=0x16520fb0 {_kCFStreamErrorCodeKey=54,
NSErrorPeerAddressKey=<CFData 0x16682e40 [0x2f752440]>{length = 16, capacity = 16, bytes = 0x10020d7eac12780b0000000000000000},
NSErrorFailingURLKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx,
NSErrorFailingURLStringKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx,
_kCFStreamErrorDomainKey=1}
只有 5% 的时间代表被正确调用并照常工作。
下面显示了我如何将请求发送到服务器并处理身份验证挑战:
- (void)postRequest
{
NSString *IP = SERVER_IP;
int port = SERVER_PORT;
NSString *url = [NSString stringWithFormat:@"http://%@:%d/Tunnel/Message.aspx", IP, port];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
NSString *xml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?><GetServerInfo></GetServerInfo>"];
[request setHTTPBody: [xml dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSLog(@"%@", challenge.protectionSpace);
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest])
{
if ([challenge previousFailureCount] == 0)
{
[[challenge sender] useCredential:[NSURLCredential credentialWithUser:USERNAME
password:PASSWORD
persistence:NSURLCredentialPersistenceNone]
forAuthenticationChallenge:challenge];
}
else
{
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}
else
{
[[challenge sender] rejectProtectionSpaceAndContinueWithChallenge:challenge];
}
}
这些代码在 iOS 7 上有效,willSendRequestForAuthenticationChallenge 在身份验证挑战期间被多次调用,但在 iOS 8 上甚至没有被调用一次!
这可能是 iOS 8 的错误或自 iOS 8 以来发生的变化?
【问题讨论】:
-
已更新。谢谢提醒。
-
顺便说一句,我在 iOS 8 上针对我的基本身份验证服务器使用了你的代码,它运行良好(尽管我显然用基本替换了你的摘要 ref)。我建议在Charles(或类似工具)中观看此内容,并查看您的服务器如何响应。在 iOS 7.1 中重复该过程并进行比较。端口和服务器名称对我来说看起来很可疑,但你说它曾经可以工作,所以我猜不是这样。
-
遗憾的是,我记得 ios7 在发布时打破了 NTLM。比较之前推荐的流量交换对于 Apple 提出的任何错误都是有用的。如果您有开发者帐户,请查看#17832727,以及以下论坛主题devforums.apple.com/message/1042503#1042503、devforums.apple.com/message/1042505#1042505
-
这方面有什么进展吗?我在使用 Digest 的 iOS 8.0.2 上看到了完全相同的问题。
-
iOS 8.1 beta 2 还是失败了,太可惜了。
标签: ios objective-c iphone nsurlconnection ios8