0xc*_*ced 4 nsurlconnection nsurlcredential ios
我试图连接到http://cmis.demo.nuxeo.org/nuxeo/atom/cmis/用NSURLConnection.这个演示Web服务记录到要求身份验证(登录:管理员/密码:管理员).
编辑:此Web服务现在发送身份验证质询,但当时没有问到该问题.
此Web服务不发送身份验证质询,因此我无法使用connection:didReceiveAuthenticationChallenge:委托方法.相反,我NSURLCredential在共享凭据存储中设置了默认值.不幸的是,此默认凭据未被使用NSURLConnection.
这是我的代码(使用ARC,在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
Run Code Online (Sandbox Code Playgroud)
由于未使用默认凭据,因此我收到html(登录页面)而不是xml.如果我将manuallyAddAuthorizationHeader变量设置为YES,则授权有效,我收到xml.
我的问题是:为什么NSURLConnection不自动使用默认的NSURLCredential?
在没有身份验证质询的情况下发送默认凭据被认为是不安全的,尤其是在您通过普通HTTP进行通信的情况下.HTTP规范说您可以主动发送凭据,但通常应该等待身份验证质询.这就是Cocoa默认提供的行为.
如果您需要主动发送凭据,则必须自己手动添加标头.您可以自己编写base-64编码,也可以使用这些CFHTTP函数为您完成编码,如下所示:
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);
Run Code Online (Sandbox Code Playgroud)
然后只需将其设置authorizationString为Authorization您的标题NSURLRequest.
(代码是从/sf/answers/35663631/公然复制的,虽然我自己多次写过类似的代码.)
| 归档时间: |
|
| 查看次数: |
4176 次 |
| 最近记录: |