AFNetworking NTLM Аутентификация?

Я бьюсь головой, пытаясь заставить AFNetworking работать, так как это мое первое приложение, которое имело дело с клиент-сервером, где я пытаюсь получить JSON с HTTPS-сервера, который требует имя пользователя / пароль. Я немного подключил его к приложению, но он продолжает выдавать ошибку 401, которую я искал как проблему базовой аутентификации.

Я в основном взял пример Twitter от AFNetworking и адаптировал его к своему проекту. В подклассе 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;
}

2 ответа

Решение

Если вы пытаетесь использовать NTLM-аутентификацию с AFNetworking, вы можете попробовать следующее:

AFNetworking поддерживает аутентификацию NTLM (или в основном любой метод аутентификации), предоставляя блочный ответ на вызовы аутентификации в целом.

Вот пример кода (при условии operation это AFHTTPRequestOperation, AFJSONRequestOperation так далее.). Перед началом операции установите блок проверки подлинности следующим образом:

[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];
   }
}];

Начните или поставьте в очередь операцию как обычно, и это должно сработать.

Это в основном метод, описанный Уэйном Хартманом в его блоге применительно к AFNetworking.

Я не мог найти 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()
Другие вопросы по тегам