如何更改NSURLSession的凭据

时间:2016-10-21 08:59:49

标签: ios authentication nsurlsession nsurlcredential nsurlcredentialstorage

我遇到以下问题:我正在向服务器发出请求,该服务器使用HTTP基本身份验证并提供给我

  • 如果我不发送身份验证,则为401
  • 如果我发送无效身份验证
  • ,则为401
  • 如果我发送有效身份验证,则为403,但禁止该资源 用户。

收到401时,我的NSURLSession足够友好,可以通过

呼叫其代表
[{'url': 'some_url', ....}, {...}, ....]

然后我可以修改发送到服务器的凭据。

但是,当收到403时,我遇到了问题。从那里我不能让会话使用任何其他凭据,而不是它用于获取403.在403,没有询问代表(这是好的,它不是401),所以我如何控制哪些凭据是将来发送给那个保护空间?即使手动清空共享的NSURLCredentialStorage和/或直接设置正确的凭据也无济于事:

URLSession(
    session: NSURLSession,
    task: NSURLSessionTask, didReceiveChallenge
    challenge: NSURLAuthenticationChallenge,
    completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)

此次通话后,NSURLCredentialStorage中列出的唯一凭证是正确的凭证 - 但下次对服务器的调用仍将包含旧凭证,这将不可避免地导致另一个403.

即使使用let credential = NSURLCredential(user: username, password: password, persistence: .ForSession) let protectionSpace = NSURLProtectionSpace( host: self.host, port: self.apiRootURL.port!.integerValue, protocol: self.apiRootURL.scheme!, realm: "MyRealm", authenticationMethod: NSURLAuthenticationMethodHTTPBasic) NSURLCredentialStorage.sharedCredentialStorage().setDefaultCredential(credential, forProtectionSpace: protectionSpace) 方法重置会话也无济于事。

TLDR ;如何更改NSURLSession在给定保护域成功使用后继续使用的凭据?

1 个答案:

答案 0 :(得分:0)

您捕获403响应消息,然后

  • 发出注销URL请求,然后发出登录URL。
  • 始终阻止凭据存储在凭据存储中,以便您始终获得回拨。
  • 在403之后删除现有凭据以强制进行回叫。

我建议使用第二种或第三种方法,具体取决于平均减少请求的结果。为了避免持久性,请传递NSURLCredentialPersistenceNone或Swift等效项,而不是告诉它在会话期间持续存在。要删除凭据,请致电removeCredential:forProtectionSpace:options:

根据您的应用程序设计和服务器设计,还有其他一些可能的工作方式:

  • 将正确的凭据预先添加到钥匙串/凭证存储中。警告:只有一个钥匙链支持它,所以如果您有多个同时发出的请求需要来自不同的帐户,这不是一个很好的方法,因为您无法控制哪个凭据获得发送给定的请求。
  • 对于需要以不同用户身份进行身份验证的内容,请使用其他身份验证领域。