【问题标题】:NSURLConnection - Disable the authentication challenge response mechanismNSURLConnection - 禁用身份验证质询响应机制
【发布时间】:2013-06-28 06:20:25
【问题描述】:

情况

  • 使用 AFNetworking (NSURLConnection) 访问我的服务器 API
  • API 需要使用令牌作为用户名的基本身份验证
  • 令牌无效时 API 返回 HTTP 401
  • 我在任何请求之前设置了基本身份验证标头
  • 如果返回 401,我会这样重试:

    AFHTTPRequestOperation *requestOperation = [MyHTTPClient.sharedClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        processSuccessBlock(operation, responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        processFailureBlock(operation, error);
    
        if (operation.response.statusCode == 401)
            [MyHTTPClient.sharedClient refreshTokenAndRetryOperation:operation success:processSuccessBlock failure:processFailureBlock];
    }];
    

问题

  • 当服务器返回带有基本身份验证质询的 HTTP 401 时,AFNetworking/NSURLConnection 两次发送相同的请求(初始请求,然后响应身份验证质询)
  • 但是由于上面的代码是我自己处理 HTTP 401,这完全没有必要,我希望它自动停止回答身份验证挑战

我的尝试

  • 使用cancelAuthenticationChallenge: 响应willSendRequestForAuthenticationChallenge: 会中止第二次调用,但它会给出错误代码 -1012 (NSURLErrorUserCancelledAuthentication) 而不是 401 并掩盖真正的响应

如何禁用身份验证质询响应机制,以便在不调用两次的情况下获得服务器响应?

【问题讨论】:

  • 在请求中设置用户名和密码:[self.request setUsername:username]; [self.request setPassword:password];
  • @GauravPatel 在什么类上设置用户名?这如何禁用身份验证质询?
  • 第一个请求如何设置认证?
  • @maccross [self setAuthorizationHeaderWithUsername:@"token" password:@"x"] in AFHTTPClient
  • @thejaz 你找到解决方案了吗?我正在研究完全相同的问题。我想自己处理 401,但 AFNetworking 正在尝试重新验证。以下关于如何实现覆盖该行为的方法的答案尚不清楚。谢谢。

标签: ios objective-c cocoa-touch nsurlconnection afnetworking


【解决方案1】:

您有几个选项可以完全自定义身份验证处理:

  1. 利用 AFURLConnectionOperation 类中的 setWillSendRequestForAuthenticationChallengeBlock:setAuthenticationAgainstProtectionSpaceBlock: 并设置相应的块,您可以在其中定制所需的机制。

    标题包含文档。

  2. AFURLConnectionOperation 的子类中覆盖connection:willSendRequestForAuthenticationChallenge:。这将有效地覆盖 AFNetworking 中的完整身份验证机制设置。

请注意,您不能禁用“服务器验证客户端身份”身份验证质询——这是服务器的一部分。您必须为请求的身份验证方法提供正确的凭据。

【讨论】:

  • 正如我在问题中所写,我已经尝试过willSendRequestForAuthenticationChallenge。问题是我如何让客户端接受 401 状态码而不发送另一个请求。
  • 您收到状态码 401,这意味着服务器要求客户端提供凭据,以便服务器可以验证客户端的身份。客户端可以取消请求,也可以使用凭据设置的所需授权标头重复相同的请求。没有其他选择。
  • 我想自己处理,所以我唯一要求的就是让它直接给我 401 响应,而不是让我取消它或请求两次。
  • 我想你不明白:作为客户端处理状态码 401(未授权)的唯一方法是取消请求或提供凭据。你不能做任何其他事情。见§10.4.2 RFC 2616
  • @CouchDeveloper 得到了 swagga。我整周看到的最佳 AFNetworking 答案。给你打勾! #twerkrandomly
【解决方案2】:

试试这个。

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    SecTrustRef trust = challenge.protectionSpace.serverTrust;
    NSURLCredential *cred;
    cred = [NSURLCredential credentialForTrust:trust];
    [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
}

【讨论】:

  • 这将有效地禁用“客户端验证服务器身份”,这是一个“服务器信任身份验证挑战”。但是,当说明问题时,OP 特别要求禁用“服务器验证客户端身份”:“当服务器返回带有 基本身份验证挑战 ...”的 HTTP 401 时 - 这是不可能的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多