我一直在搜索 stackoverflow、google、apple 和其他地方。提供的提示看起来很有希望,我实现了它们,但总的来说似乎不起作用或无法强制执行。
问题:我有一个具有特定凭据的 NSURLConnection
。然后我注销,在那里我清除凭据,保护空间,我删除所有缓存的响应并删除 sharedHTTPCookieStorage
中的所有 cookie 但是几秒钟后再次调用我的身份验证请求时即使使用错误的凭据我仍然我正在使用旧的(已删除的)凭据
这里是一些代码摘录,其中删除了凭据
NSDictionary *credentialsDict = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials];
if ([credentialsDict count] > 0) {
// the credentialsDict has NSURLProtectionSpace objs as keys and dicts of userName => NSURLCredential
NSEnumerator *protectionSpaceEnumerator = [credentialsDict keyEnumerator];
id urlProtectionSpace;
// iterate over all NSURLProtectionSpaces
while (urlProtectionSpace = [protectionSpaceEnumerator nextObject]) {
NSEnumerator *userNameEnumerator = [[credentialsDict objectForKey:urlProtectionSpace] keyEnumerator];
id userName;
// iterate over all usernames for this protectionspace, which are the keys for the actual NSURLCredentials
while (userName = [userNameEnumerator nextObject]) {
NSURLCredential *cred = [[credentialsDict objectForKey:urlProtectionSpace] objectForKey:userName];
WriteLog(@"Method: switchView removing credential %@",[cred user]);
[[NSURLCredentialStorage sharedCredentialStorage] removeCredential:cred forProtectionSpace:urlProtectionSpace];
}
}
}
然后我删除所有缓存的响应
NSURLCache *sharedCache = [NSURLCache sharedURLCache];
[sharedCache removeAllCachedResponses];
然后我删除所有 cookie
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [cookieStorage cookies];
for (NSHTTPCookie *cookie in cookies) {
[cookieStorage deleteCookie:cookie];
NSLog(@"deleted cookie");
}
我也试过不使用 cookies 和其他政策
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
[request setHTTPShouldHandleCookies:NO];
if(self.currentCookies != nil){
[request setAllHTTPHeaderFields:
[NSHTTPCookie requestHeaderFieldsWithCookies:nil]];
}
theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
我还在此处尝试了这个关于专门存储 cookie 并再次传递它们的提示。 http://www.hanspinckaers.com/multiple-nsurlrequests-with-different-cookies .网络上还有另一个博客建议在每个 URL 中添加一个“#”以强制执行重新身份验证,这有效但不能解决问题,因为我需要依靠 session 的凭据和使用完全不同的凭据的能力。
这是错误还是已知问题,我该如何真正解决这个问题... 坦率地说:我到底做错了什么?
这真的很烦我,让我无法继续我的工作。
我将不胜感激任何意见!
非常感谢!
最佳答案
不幸的是,这个问题似乎没有解决方案。
您可以使用 NSURLCredentialPersistenceNone 或 # 技巧,或者您可以定义 'connectionShouldUseCredentialStorage' 委托(delegate)方法以返回 NO。如果您每次都这样做,而您的应用从不保留 session 的凭据,这将强制对每个请求进行质询。
对于只执行最少请求或最终使用 session cookie 进行身份验证的应用,这可能没问题。
对于发送大量请求的应用,这些解决方案都会对每个请求产生 401 响应,并且额外的质询-响应会增加数据和性能。
如果您可以保留 session 的凭据存储,直到您需要注销然后切换到其中一种变通方法,那就太好了,但这是不可能的。
一旦您为 session 存储了一次凭据,它们就会为整个 TLS session 缓存。这导致需要等待大约 10 分钟,直到该 session 结束。
您可以在以下位置阅读有关此问题的更多信息:http://developer.apple.com/library/ios/qa/qa1727/_index.html
该文档提到了一个有限的解决方法,涉及附加“.”。到服务器名称的末尾。然而,我一直无法让它工作。
除此之外,这些是我能想到的解决方案:
1) 始终使用应生成 401 的 NSURLCredentialPersistenceNone 和 connectionShouldUseCredentialStorage 解决方法。自己将基本身份验证 header 添加到请求中。这应该可以防止额外的 401,同时也可以绕过凭据存储。添加该授权的代码如下所示:
NSString *s ;
NSString *authStr ;
s = [NSString stringWithFormat:@"%@:%@",user,password] ;
s = [YourBase64Encoder base64EncodingForData:[NSData dataWithBytes:[s UTF8String] length:strlen([s UTF8String])]];
authStr = [NSString stringWithFormat:@"Basic %@",s] ;
[request setValue:authStr forHTTPHeaderField:@"Authorization"] ;
我不知道其他身份验证方法如何实现这一点,但我认为这是可能的。
2) 将问题告知用户并要求他们重启应用
3) 实现您自己的基于 HTTP 检索机制的低级套接字,完全绕过 CFNetwork。祝你好运:>)
关于objective-c - 无法使用不同的 NSURL 凭据进行身份验证(使用旧的已删除凭据),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7471141/