3

我正在努力让 AFNetworking 工作,因为这是我第一个必须处理客户端/服务器的应用程序,我试图从需要用户名/密码的 HTTPS 服务器获取 JSON。我把它与应用程序联系起来了,但它一直抛出 401 错误,我认为这是基本身份验证问题。

我基本上从 AFNetworking 中获取了 twitter 示例并将其改编为我的项目。在 AFHTTPClient 的子类中,我在 initWithBaseURL 中添加了另一行,它仍然会引发错误。我添加的行是 setAuthorizationHeaderWithUsername

- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
    return nil;
}

[self registerHTTPOperationClass:[AFJSONRequestOperation class]];

// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[self setDefaultHeader:@"Accept" value:@"application/json"];
[self setAuthorizationHeaderWithUsername:@"myusername" password:@"my password"];

return self;
}
4

2 回答 2

5

如果您尝试将 NTLM 身份验证与 AFNetworking 一起使用,您可以尝试以下操作:

AFNetworking 通常通过提供基于块的对身份验证挑战的响应来支持 NTLM 身份验证(或基本上任何身份验证方法)。

这是一个代码示例(假设operation是 aAFHTTPRequestOperationAFJSONRequestOperation)。在开始操作之前,像这样设置身份验证挑战块:

[operation setAuthenticationChallengeBlock:
 ^( NSURLConnection* connection, NSURLAuthenticationChallenge* challenge )
{
   if( [[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodNTLM )
   {
      if( [challenge previousFailureCount] > 0 )
      {
         // Avoid too many failed authentication attempts which could lock out the user
         [[challenge sender] cancelAuthenticationChallenge:challenge];
      }
      else
      {
         [[challenge sender] useCredential:[NSURLCredential credentialWithUser:@"username" password:@"password" persistence:NSURLCredentialPersistenceForSession] forAuthenticationChallenge:challenge];
      }
   }
   else
   {
      // Authenticate in other ways than NTLM if desired or cancel the auth like this:
      [[challenge sender] cancelAuthenticationChallenge:challenge];
   }
}];

像往常一样启动或排队操作,这应该可以解决问题。

这基本上就是 Wayne Hartman在他的博客中描述的应用于 AFNetworking 的方法。

于 2013-01-10T14:10:58.123 回答
4

我找不到setAuthenticationChallengeBlock:接受答案的所有者提到的方法(也许它已被较新的版本删除?)但是,我想出了基于非块的 NTLM 身份验证解决方案,如下所示。(它实际上是用 Swift 编写的,但将其转换为 Objective C 应该不是问题)您只需在您的AFHTTPRequestOperation实例中设置您的凭据对象:

var reqSerializer:AFHTTPRequestSerializer = AFHTTPRequestSerializer()
var request = reqSerializer.requestWithMethod("GET", URLString: "<URL>", parameters: nil, error: nil)  
var oper = AFHTTPRequestOperation(request: request)

var respSerializer = AFXMLParserResponseSerializer()
oper.responseSerializer = respSerializer

var creds:NSURLCredential = NSURLCredential(user: "<DOMAIN\\USER>", password: "<PASSWORD>", persistence: NSURLCredentialPersistence.None)
oper.credential = creds

oper.setCompletionBlockWithSuccess({ (oper:AFHTTPRequestOperation!, obj:AnyObject!) -> Void in
        //handle success

    }, failure: { (oper:AFHTTPRequestOperation!, err:NSError!) -> Void in
        //handle failure
})

oper.start()
于 2014-09-23T10:40:42.430 回答