我正在使用一个使用ASIHTTPRequest与使用NTLM身份验证的Web服务进行交互的iPhone应用程序。凭证应存储在钥匙串中。它记录正常,但我想有一个注销按钮,清除应用程序的凭据,我无法让它工作。
点击退出按钮后,我希望当我返回查询服务器的视图时,系统会提示我再次登录。但是,这不会发生,并且对服务器的调用仍然会进行身份验证。
发出请求的代码如下所示:
NSString *urlString = [NSString stringWithFormat:@"http://myserver.mydomain.com/myapp/items/%@", itemGroupId];
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setUseKeychainPersistence:YES];
[request setShouldPresentAuthenticationDialog:YES];
[request setRequestMethod:@"POST"];
[request addRequestHeader:@"content-type" value:@"application/json;charset=utf-8"];
[request addRequestHeader:@"content-length" value:@"0"];
[request setDelegate:self];
[request startAsynchronous];
对于退出,我尝试过调用:
[ASIHTTPRequest removeCredentialsForHost:@"myserver.mydomain.com" port:0 protocol:@"http" realm:nil];
但这不起作用。该方法中的代码没有找到保存的NSURLCredential,因此它可以将其删除,即使这些参数是我见过的传递给saveCredentials:forHost:port:protocol:realm:首先。 / p>
我也试过调用clearSession,我尝试在使用setUseSessionPersistence创建请求时完全禁用会话持久性,但没有运气。
我还尝试使用基于this example的代码循环浏览应用程序钥匙串中的所有凭据并将其全部删除:
NSURLCredentialStorage *store = [NSURLCredentialStorage sharedCredentialStorage];
for (NSURLProtectionSpace *space in [store allCredentials]) {
NSDictionary *userCredentialMap = [store credentialsForProtectionSpace:space];
for (NSString *user in userCredentialMap) {
NSURLCredential *credential = [userCredentialMap objectForKey:user];
[store removeCredential:credential forProtectionSpace:space];
}
}
这种方式有效,因为下次启动应用程序时,它会再次提示登录。但如果应用继续运行,它不会提示再次登录。
答案 0 :(得分:0)
您确定使用端口0并且没有领域是正确的吗? 只是为了确保我从我的connect-url-string创建一个NSURL(我用于所有ASIHTTPRequest的相同url),并从中检索主机,端口和协议。我现在只需要手工提到这个领域。
使用此代码,我可以在我的应用中成功注销:
// clear keychain
NSURL *url = [NSURL URLWithString:kConnectorUrlString];
[ASIHTTPRequest removeCredentialsForHost:[url host] port:[[url port] intValue] protocol:[url scheme] realm:kConnectorRealm];
当我的应用继续运行时,我的应用再次提示我。 我使用的相同参数也被传递给saveCredentials。