NSURLCredential 和 NSURLConnection
我一直在尝试寻找一种在使用 NSURLCredentialPersistenceForSession 的 NSURLConnection 设置 NSURLCredential 后取消设置凭据的方法,但我找不到有效的解决方案。从 NSURLCredentialStorage 中删除 NSURLCredential 只会将其从存储中删除,而不是从 NSURLConnection 缓存中删除。我尝试关闭缓存,但它仍然保留。我需要它是 NSURLCredentialPersistenceForSession 因为我不希望它上传大数据然后返回您需要验证的消息然后使用 NSURLConnection 进行身份验证然后重新发送大数据,我只想验证一次并发送大数据一次。我有一种在发送大数据之前通过检查某些属性进行身份验证的方法,但这不允许我注销或重新请求身份验证。我正在编写一个 WebDav 客户端,以便您了解我的立场,我需要取消设置凭据的原因是如果有人在 WebDav 服务器上拥有多个帐户并想要登录另一个帐户。我尝试查看 cookie,看看它是否在那里设置了某些内容,但没有。我知道这仅适用于会话,这意味着一旦您退出并重新启动应用程序,您就可以以其他用户身份登录。但这可能会让一些人感到困惑。我想过编写自己的身份验证系统,但我不知道这需要多长时间。
抱歉,如果上面的消息太长,我只是确保详细解释了所有内容,以便有人可以尝试帮助我提供有效的答案,而不是“去这里引导我尝试一下”。
感谢您的帮助,
壁虎先生。
更新:示例代码。
CFHTTPMessageRef message = [self httpMessageFromResponse:response];
authentication = CFHTTPAuthenticationCreateFromResponse(kCFAllocatorDefault, message);
CFHTTPMessageRef message = [self httpMessageFromRequest:request];
CFStreamError error;
CFHTTPMessageApplyCredentials(message, authentication, (CFStringRef)[credentials user], (CFStringRef)[credentials password], &error);
NSLog(@"%d", error.error); // Returns -1000
CFStringRef value = CFHTTPMessageCopyHeaderFieldValue(message, CFSTR("Authorization"));
NSLog(@"%@", (NSString *)value); // Returns NULL
if (value!=NULL)
CFRelease(value);
更新:我尝试删除凭据的代码。
- (void)resetCredentials {
NSURLCredentialStorage *store = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *allCredentials = [store allCredentials];
NSArray *keys = [allCredentials allKeys];
for (int i=0; i<[keys count]; i++) {
NSURLProtectionSpace *protectionSpace = [keys objectAtIndex:i];
NSDictionary *userToCredentialMap = [store credentialsForProtectionSpace:protectionSpace];
NSArray *mapKeys = [userToCredentialMap allKeys];
for (int u=0; u<[mapKeys count]; u++) {
NSString *user = [mapKeys objectAtIndex:u];
NSURLCredential *credential = [userToCredentialMap objectForKey:user];
NSLog(@"%@", credential);
[store removeCredential:credential forProtectionSpace:protectionSpace];
}
}
}
I have been trying to search for a way to unset the credentials once you set a NSURLCredential with a NSURLConnection that is using NSURLCredentialPersistenceForSession, but I couldn't find a working solution. Removing the NSURLCredential from the NSURLCredentialStorage only removes it from the storage and not from the NSURLConnection cache. I tried turning cache off and it still keeps it. I need it to be NSURLCredentialPersistenceForSession as I don't want it to be uploading the large data then getting back the you need to authenticate message then authenticating with NSURLConnection and then resending the large data, I just want to authenticate once and send the large data once. I have a way to authenticate before sending the large data by checking some properties, but that doesn't allow me to logout or re-ask for authentication. I'm writing a WebDav client just so you understand where I stand, and the reason I need to unset the credentials is if someone has multiple accounts on the WebDav server and wants to login to another account. I tried looking into the cookies to see if it set something there, but it doesn't. I know it's only for the session, which means once your quit and relaunch the application, you can login as the other user. But that may confuse some people. I thought about writing my own Authentication system, but I wouldn't know how long that'll take.
Sorry if the above message is too long, I am just making sure I explain everything in detail so someone can try to help me with a valid answer and not a, go here leading me to something I tried.
Thanks for any help,
Mr. Gecko.
Update: Example code.
CFHTTPMessageRef message = [self httpMessageFromResponse:response];
authentication = CFHTTPAuthenticationCreateFromResponse(kCFAllocatorDefault, message);
CFHTTPMessageRef message = [self httpMessageFromRequest:request];
CFStreamError error;
CFHTTPMessageApplyCredentials(message, authentication, (CFStringRef)[credentials user], (CFStringRef)[credentials password], &error);
NSLog(@"%d", error.error); // Returns -1000
CFStringRef value = CFHTTPMessageCopyHeaderFieldValue(message, CFSTR("Authorization"));
NSLog(@"%@", (NSString *)value); // Returns NULL
if (value!=NULL)
CFRelease(value);
Update: Code that I tried with removing credentials.
- (void)resetCredentials {
NSURLCredentialStorage *store = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *allCredentials = [store allCredentials];
NSArray *keys = [allCredentials allKeys];
for (int i=0; i<[keys count]; i++) {
NSURLProtectionSpace *protectionSpace = [keys objectAtIndex:i];
NSDictionary *userToCredentialMap = [store credentialsForProtectionSpace:protectionSpace];
NSArray *mapKeys = [userToCredentialMap allKeys];
for (int u=0; u<[mapKeys count]; u++) {
NSString *user = [mapKeys objectAtIndex:u];
NSURLCredential *credential = [userToCredentialMap objectForKey:user];
NSLog(@"%@", credential);
[store removeCredential:credential forProtectionSpace:protectionSpace];
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我正在使用 webdav 服务器并遇到类似的问题。我在苹果的 AdvancedURLConnection 项目的示例代码中找到了解决方案。看来秘密是迭代保护空间,然后迭代每个空间的凭据。它可能不必要地过于复杂,但它对我有用。
I'm working with a webdav server and had a similar issue. I found a solution within the sample code for apple's AdvancedURLConnection's project. It appears that the secret is to iterate over the protection spaces and then the credentials for each space. It's probably needlessly over complex but it works for me.