NSURLConnection不使用默认凭据 [英] NSURLConnection does not use the default credential

查看:131
本文介绍了NSURLConnection不使用默认凭据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试连接到 http://cmis.demo.nuxeo。 org / nuxeo / atom / cmis / NSURLConnection 。此演示Web服务记录以要求身份验证(登录:管理员/密码) :管理员)。

I'm trying to connect to http://cmis.demo.nuxeo.org/nuxeo/atom/cmis/ with NSURLConnection. This demo web service is documented to require authentication (login: Administrator / password: Administrator).

编辑:此网络服务现在发送身份验证质询,当时问题未被提出。

Edit: This web service now sends an authentication challenge, it was not at the time the question was asked.

此网络服务发送身份验证质询,因此我无法使用 connection:didReceiveAuthenticationChallenge:委托方法。相反,我在共享凭据存储中设置了默认的 NSURLCredential 。不幸的是, NSURLConnection 不使用此默认凭证。

This web service does not send an authentication challenge, so I can't use the connection:didReceiveAuthenticationChallenge: delegate method. Instead I set a default NSURLCredential in the shared credential storage. Unfortunately, this default credential is not used by NSURLConnection.

这是我的代码(使用ARC,在iOS上测试过) 5):

Here is my code (using ARC, tested on iOS 5):

@implementation ViewController
{
    NSMutableData *responseData;
}

- (IBAction) connect:(id)sender
{
    NSString *user = @"Administrator";
    NSString *password = @"Administrator";
    NSURL *nuxeoURL = [NSURL URLWithString:@"http://cmis.demo.nuxeo.org/nuxeo/atom/cmis/"];

    NSURLCredential *credential = [NSURLCredential credentialWithUser:user password:password persistence:NSURLCredentialPersistenceForSession];
    NSString *host = [nuxeoURL host];
    NSNumber *port = [nuxeoURL port];
    NSString *protocol = [nuxeoURL scheme];
    NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:host port:[port integerValue] protocol:protocol realm:nil authenticationMethod:NSURLAuthenticationMethodHTTPBasic];
    [[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nuxeoURL];
    BOOL manuallyAddAuthorizationHeader = NO;
    if (manuallyAddAuthorizationHeader)
    {
        NSData *authoritazion = [[NSString stringWithFormat:@"%@:%@", user, password] dataUsingEncoding:NSUTF8StringEncoding];
        NSString *basic = [NSString stringWithFormat:@"Basic %@", [authoritazion performSelector:@selector(base64Encoding)]];
        [request setValue:basic forHTTPHeaderField:@"Authorization"];
    }
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];
}

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    responseData = [NSMutableData data];
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [responseData appendData:data];
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"connectionDidFinishLoading:%@", connection);
    NSLog(@"%@", [[NSString alloc] initWithData:responseData encoding:NSISOLatin1StringEncoding]);
}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"connection:%@ didFailWithError:%@", connection, error);
}

@end

由于默认凭证不是使用过,我收到html(登录页面)而不是xml。如果我将 manualAddAuthorizationHeader 变量设置为 YES ,则授权有效,我收到xml。

Since the default credential is not used, I receive html (login page) instead of xml. If I set the manuallyAddAuthorizationHeader variable to YES, then authorization works and I receive xml.

我的问题是:为什么 NSURLConnection 自动使用默认 NSURLCredential

My question is: why does NSURLConnection does not automatically use the default NSURLCredential?

推荐答案

在没有身份验证质询的情况下发送默认凭据会被认为是不安全的,特别是在您遇到的情况下通过纯HTTP进行通信。 HTTP规范说明可以主动发送凭据,但您通常应该等待身份验证质询。这就是Cocoa默认提供的行为。

Sending the default credential without an authentication challenge is considered insecure, especially in the case where you're communicating over plain HTTP. The HTTP spec says that you can send credentials proactively, but that you should usually wait for an authentication challenge. And that's the behavior that Cocoa provides by default.

如果您需要主动发送凭据,那么您必须自己手动添加标头。您可以自己编写base-64编码,或者您可以使用 CFHTTP 函数为您执行此操作,如下所示:

If you need to proactively send the credentials, then you'll have to manually add the headers yourself. You can just base-64 encode it yourself, or you can use the CFHTTP functions to do it for you, like so:

CFHTTPMessageRef dummyRequest =
    CFHTTPMessageCreateRequest(
        kCFAllocatorDefault,
        CFSTR("GET"),
        (CFURLRef)[urlRequest URL],
        kCFHTTPVersion1_1);
CFHTTPMessageAddAuthentication(
    dummyRequest,
    nil,
    (CFStringRef)username,
    (CFStringRef)password,
    kCFHTTPAuthenticationSchemeBasic,
    FALSE);
authorizationString =
    (NSString *)CFHTTPMessageCopyHeaderFieldValue(
        dummyRequest,
        CFSTR("Authorization"));
CFRelease(dummyRequest);

然后只需设置 authorizationString 作为授权 NSURLRequest 中的标题。

Then just set the authorizationString as the Authorization header in your NSURLRequest.

(代码被公然复制)来自 https://stackoverflow.com/a/509480/100478 ,虽然我自己多次编写类似的代码。 )

(Code copied blatantly from https://stackoverflow.com/a/509480/100478, though I've written similar code myself many times.)

这篇关于NSURLConnection不使用默认凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆