如何在Object-c中格式化来自iphone的azure表存储请求
我需要帮助从iPhone应用程序获取azure表存储请求的正确标题。 我一直在使用这两篇文章来尝试正确加密密钥,但仍然有问题: 服务正在为我的请求返回一个错误: 服务器无法验证请求,出现以下错误:如何在Object-c中格式化来自iphone的azure表存储请求,iphone,objective-c,azure,Iphone,Objective C,Azure,我需要帮助从iPhone应用程序获取azure表存储请求的正确标题。 我一直在使用这两篇文章来尝试正确加密密钥,但仍然有问题: 服务正在为我的请求返回一个错误: 服务器无法验证请求,出现以下错误: Make sure the value of Authorization header is formed correctly including the signature. 我正在使用以下代码发出请求: NSDate *now = [[NSDate alloc] init]; NSStr
Make sure the value of Authorization header is formed correctly including the signature.
我正在使用以下代码发出请求:
NSDate *now = [[NSDate alloc] init];
NSString *dateString = [self rfc1123String:now];
NSString *messageToSign = [NSString stringWithFormat:@"%@\n/%@/%@", dateString, AZURE_ACCOUNT_NAME, table];
[Base64 initialize];
//xxx in my code is my primary access shared key
NSString *key = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
const char *cData = [messageToSign cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hash = [Base64 encode:HMAC];
NSLog(@"Encoded hash: %@", hash);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request addValue:[NSString stringWithFormat:@"SharedKeyLite %@:%@", AZURE_ACCOUNT_NAME, hash] forHTTPHeaderField:@"Authorization"];
[request addValue:dateString forHTTPHeaderField:@"x-ms-date"];
[request addValue:@"application/atom+xml, application/xml" forHTTPHeaderField:@"Accept"];
[request addValue:@"UTF-8" forHTTPHeaderField:@"Accept-Charset"];
NSLog(@"Headers: %@", [request allHTTPHeaderFields]);
NSLog(@"URL: %@", [[request URL] absoluteString]);
return request;
Accept = "application/atom+xml, application/xml";
"Accept-Charset" = "UTF-8";
Authorization = "SharedKeyLite powderdayalarm:xwT1purDtREtxauVr6Bhvdz/2ObLh2J0lMw/prBBQBE=";
"X-Ms-Date" = "Fri, 05 Nov 2010 18:26:00 GMT";
这将导致为请求生成以下标头:
NSDate *now = [[NSDate alloc] init];
NSString *dateString = [self rfc1123String:now];
NSString *messageToSign = [NSString stringWithFormat:@"%@\n/%@/%@", dateString, AZURE_ACCOUNT_NAME, table];
[Base64 initialize];
//xxx in my code is my primary access shared key
NSString *key = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
const char *cData = [messageToSign cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hash = [Base64 encode:HMAC];
NSLog(@"Encoded hash: %@", hash);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request addValue:[NSString stringWithFormat:@"SharedKeyLite %@:%@", AZURE_ACCOUNT_NAME, hash] forHTTPHeaderField:@"Authorization"];
[request addValue:dateString forHTTPHeaderField:@"x-ms-date"];
[request addValue:@"application/atom+xml, application/xml" forHTTPHeaderField:@"Accept"];
[request addValue:@"UTF-8" forHTTPHeaderField:@"Accept-Charset"];
NSLog(@"Headers: %@", [request allHTTPHeaderFields]);
NSLog(@"URL: %@", [[request URL] absoluteString]);
return request;
Accept = "application/atom+xml, application/xml";
"Accept-Charset" = "UTF-8";
Authorization = "SharedKeyLite powderdayalarm:xwT1purDtREtxauVr6Bhvdz/2ObLh2J0lMw/prBBQBE=";
"X-Ms-Date" = "Fri, 05 Nov 2010 18:26:00 GMT";
请求的规格如下所示:
指的是:
此格式支持共享密钥和
所有版本的共享密钥Lite
表服务和共享密钥Lite
对于2009-09-19版本的Blob
和排队服务。此格式是
与上一次使用的相同
存储服务的版本。
构造CanonicalizedResource
此格式的字符串如下所示:
以空字符串开头,附加正斜杠/,
后跟帐户的名称
拥有正在访问的资源的
追加资源的编码URI路径。如果请求URI地址为
资源的一个组件,append
适当的查询字符串。这个
查询字符串应包括
问号和comp参数
例如,comp=元数据。不
其他参数应包括在
查询字符串
对签名进行编码
要对签名进行编码,请调用
HMAC-SHA256算法在计算机上的实现
UTF-8编码的签名字符串和
将结果编码为Base64。使用
以下格式显示为
伪代码:复制
签名=Base64HMAC-SHA256UTF8StringToSign
我似乎找不到这个问题的根源。而且似乎并没有太多人从iphone发出azure请求:
谢谢
ScottSmarx在Azure论坛上向我解释了最佳实践。他写道: 从客户端访问存储有两种安全的方法: 1.对blob使用共享访问签名。在服务器端,您可以生成签名(基本上是一个已签名的URL),该签名的范围可能仅限于特定的blob、特定的权限和有限的时间。 2.仅从客户端访问web服务,并让web服务访问存储。
在这两种情况下,中间都有一台服务器,就像在web应用程序中一样。浏览器从不与SQL数据库通信。。。它与您的网站对话,然后与数据库对话。这有什么使用案例?此iPhone应用程序的每个用户都拥有一个存储帐户?大多数人不直接从手机访问存储的原因是,没有安全模型可以做到这一点,而不会将密钥泄露给客户端,从而使每个人都可以完全删除您的所有数据,等等。我假设在通过网络发送身份验证之前,获取我的密钥并对其进行加密就足够安全了。您是否暗示在上面我的链接中指定的azure表存储的REST规范中没有安全模型?用户将如何提取密钥?@ScottChamberlin非常感谢这个问题。我使用了相同的方法,也遇到了相同的错误。你能告诉我如何解决这个问题吗?希望你的帮助。提前谢谢。我也面临同样的错误。你能指导我如何解决这个错误吗?希望你的帮助。答案是不要从iPhone客户端访问表存储。您应该创建一个访问存储的Web服务,并从iphone客户端访问该Web服务。