首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以使用NSURLCredentialStorage进行HTTP基本认证?

是否可以使用NSURLCredentialStorage进行HTTP基本认证?
EN

Stack Overflow用户
提问于 2009-02-01 17:42:58
回答 4查看 32.5K关注 0票数 19

我设置了一个cocoa类,我想用它来连接到我正在构建的RESTful web服务。我已经决定在我的PHP后端使用HTTP Basic Authentication,就像这样…

代码语言:javascript
复制
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="My Realm"');
    header('HTTP/1.0 401 Unauthorized');
    //Stuff that users will see if they click 'Cancel'
    exit;
}
else {
    //Validation Code
    echo "You entered info.";
}
?>

在这一点上,我使用的是同步NSURLConnection,据我所知,苹果文档中指出,它对身份验证的支持较少。

但这到底有没有可能呢?我可以很容易地通过NSURLProtectionSpaces或NSURLCredentials或任何身份验证类进行cookie身份验证。另外,有没有什么资源可以让我了解更多关于Cocoa身份验证类的信息?

谢谢。

更新: mikeabdullahuk您提供的代码(第二个示例)与我编写的代码几乎相同。我做了进一步的调查,发现NSURLConnection返回了一个错误的…

代码语言:javascript
复制
Error Domain=NSURLErrorDomain Code=-1012 UserInfo=0x1a5170 "Operation could not be completed. (NSURLErrorDomain error -1012.)"

代码对应于NSURLErrorUserCancelledAuthentication。因此,很明显,我的代码没有访问NSURLCredentialStorage,而是取消了身份验证。这可能与PHP HTTP身份验证函数有关吗?在这一点上我很困惑。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-02-02 00:01:26

同步NSURLConnection绝对可以与NSURLCredentialStorage一起工作。事情通常是这样的:

  1. NSURLConnection向服务器请求页面response
  2. NSURLConnection服务器回复401
  3. 查看它可以从URL收集哪些凭据如果URL提供完整的凭据(用户名和密码),NSURLConnection还将咨询NSURLCredentialStorage以填补空白
  4. 如果仍未确定完整的凭据,NSURLConnection将发送D19委托方法,要求提供完整凭据d22现在终于具有完整的凭据,它将重试包括授权数据在内的原始请求。

通过使用同步连接方法,您只会在步骤5 (提供自定义身份验证的能力)中失去。因此,您可以在URL中预先提供身份验证凭据,或者在发送请求之前将它们放在NSURLCredentialStorage中。例如:

代码语言:javascript
复制
NSURLRequest *request =
  [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://user:pass@example.com"]];

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

或者:

代码语言:javascript
复制
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];
票数 63
EN

Stack Overflow用户

发布于 2009-02-03 23:34:17

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

代码语言:javascript
复制
// 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的情况,因为服务器实际上并没有发送HTTP401(例如,它发送的是常规页面)。

票数 12
EN

Stack Overflow用户

发布于 2009-02-02 17:54:19

我要指出的是,mikeabdullahuk的答案是好的,但如果你使用NSURLCredentialPersistencePermanent而不是每个会话,它会将凭证存储在用户的密钥链中,所以下次你可以检查NSURLCredentialStorage中保护空间的默认凭证的非nil值,如果你得到一个非nil值,你只需传递凭证即可。我现在正在为我正在编写的delicious.com客户端使用这个方法,它在我的测试中工作得非常好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/501231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档