当前位置:  开发笔记 > IOS > 正文

我可以使用NSURLCredentialStorage进行HTTP基本身份验证吗?

如何解决《我可以使用NSURLCredentialStorage进行HTTP基本身份验证吗?》经验,为你挑选了2个好方法。

我有一个cocoa类设置,我想用它连接到我正在构建的RESTful Web服务.我决定在我的PHP后端使用HTTP基本身份验证,就像这样......


此时我正在使用同步NSURLConnection,我了解Apple文档状态对身份验证的支持较少.

但它甚至可能吗?我可以非常轻松地进行cookie身份验证,无需NSURLProtectionSpaces或NSURLCredentials或任何身份验证类.此外,是否有任何资源,我可以阅读更多关于Cocoa身份验证类?

谢谢.

更新:mikeabdullahuk您提供的代码(第二个示例)几乎与我所写的相同.我做了一些调查,发现NSURLConnection正在返回错误......

Error Domain=NSURLErrorDomain Code=-1012 UserInfo=0x1a5170 "Operation could not be completed. (NSURLErrorDomain error -1012.)"

该代码对应于NSURLErrorUserCancelledAuthentication.显然我的代码没有访问NSURLCredentialStorage,而是取消了身份验证.这可能与PHP HTTP身份验证功能有关吗?我现在很困惑.



1> Mike Abdulla..:

同步NSURLConnection绝对可以使用NSURLCredentialStorage.事情通常是如何运作的:

    NSURLConnection 从服务器请求页面

    服务器回复401响应

    NSURLConnection 看看它可以从URL中收集哪些凭据

    如果URL并没有提供完整的凭据(用户名和密码),NSURLConnection亦会咨询NSURLCredentialStorage,填补了国内空白

    如果仍未确定完整凭据,NSURLConnection则将发送-connection:didReceiveAuthenticationChallenge:委托方法请求凭据

    如果NSURLConnection现在最终具有完整凭证,则它将重试原始请求,包括授权数据.

通过使用同步连接方法,您只能在步骤5中失去提供自定义身份验证的能力.因此,您可以在URL中预先提供身份验证凭据,也可以NSURLCredentialStorage在发送请求之前将其置于其中.例如

NSURLRequest *request =
  [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://user:pass@example.com"]];

[NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];

要么:

NSURLCredential *credential = [NSURLCredential credentialWithUser:@"user"
                                                         password:@"pass"
                                                      persistence:NSURLCredentialPersistenceForSession];

NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
  initWithHost:@"example.com"
  port:0
  protocol:@"http"
  realm:nil
  authenticationMethod:nil];


[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential
                                                    forProtectionSpace:protectionSpace];
[protectionSpace release];

NSURLRequest *request =
  [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]];

[NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];


根据sendSynchronousRequest的apple文档:'如果需要进行身份验证以下载请求,则必须将所需的凭据指定为URL的一部分...'我自己的经验将证实这一点; 也就是说,使用NSURLCRedentialStorage不能与sendSynchronousRequest一起使用.

2> Matt Gallagh..:

在401或其他身份验证挑战不可接受/不可能的情况下,我有时会使用虚拟CFHTTPMessage生成验证行,然后将其复制回NSURLRequest:

// assume NSString *username and *password exist and NSURLRequest *urlRequest
// exists and is fully configured except for HTTP Basic Authentication.. 

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);

[urlRequest setValue:authorizationString forHTTPHeaderField:@"Authorization"];

这似乎完全是一种奇怪的方式,但它可以容忍用户名/密码不是URL清理的情况,以及NSURLRequest拒绝咨询NSURLCredentialStorage的情况,因为服务器实际上并没有发送HTTP 401(例如它发送改为常规页面).

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有