我想从 Swift 访问 azure 表存储。 制作表头的指令是here 但是,我尝试构建请求但无法使其工作:
let urlString = "https://<myaccount>.table.core.windows.net/MyTable"
let storageUrl = NSURL( string: urlString)
let request = NSMutableURLRequest(URL: storageUrl!)
//making the date
let currentDate = NSDate()
let httpFormatter = NSDateFormatter()
httpFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
httpFormatter.dateFormat = "EEE',' dd MMM yyyy HH':'mm':'ss z"
let httpTime = httpFormatter.stringFromDate(currentDate)
print(httpTime)
let signingString = "GET\n\n\n\(httpTime)\n/<myaccount>/MyTable"
print(signingString)
let keyString = <myKeyString>
let keyData = keyString.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion: false)!
let signingData = signingString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let length:Int = Int(CC_SHA256_DIGEST_LENGTH)
let hashResult = UnsafeMutablePointer<CUnsignedChar>.alloc(length)
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyData.bytes, Int(keyData.length), signingData.bytes, Int(signingData.length), hashResult)
print(hashResult)
let hash = NSData(bytes: hashResult, length: Int(CC_SHA256_DIGEST_LENGTH))
let hashString = hash.base64EncodedStringWithOptions(NSDataBase64EncodingOptions([]))
hashResult.destroy()
//print(hashString)
request.setValue("SharedKeyLite <myaccount>:\(hashString)", forHTTPHeaderField: "Authorization")
request.setValue("0", forHTTPHeaderField: "Content-Length")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(httpTime, forHTTPHeaderField: "x-ms-date")
request.setValue("", forHTTPHeaderField: "Date")
request.HTTPMethod = "GET"
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in
if let data = data {
let datastring = NSString(data:data, encoding:NSUTF8StringEncoding)
print( datastring! )
//print(response)
} else {
print( error )
}
}).resume()
在下面的正确答案之后,我对字符串进行了扩展,因此 hmac 签名非常容易做到:
//
// CryptoExtensions.swift
// LaochTestProject
//
// Created by Lars Christoffersen on 02/01/16.
// Copyright © 2016 Lars Christoffersen. All rights reserved.
//
import Foundation
enum CryptoAlgorithm {
case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
var HMACAlgorithm: CCHmacAlgorithm {
var result: Int = 0
switch self {
case .MD5: result = kCCHmacAlgMD5
case .SHA1: result = kCCHmacAlgSHA1
case .SHA224: result = kCCHmacAlgSHA224
case .SHA256: result = kCCHmacAlgSHA256
case .SHA384: result = kCCHmacAlgSHA384
case .SHA512: result = kCCHmacAlgSHA512
}
return CCHmacAlgorithm(result)
}
var digestLength: Int {
var result: Int32 = 0
switch self {
case .MD5: result = CC_MD5_DIGEST_LENGTH
case .SHA1: result = CC_SHA1_DIGEST_LENGTH
case .SHA224: result = CC_SHA224_DIGEST_LENGTH
case .SHA256: result = CC_SHA256_DIGEST_LENGTH
case .SHA384: result = CC_SHA384_DIGEST_LENGTH
case .SHA512: result = CC_SHA512_DIGEST_LENGTH
}
return Int(result)
}
}
extension String {
func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
let strData = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let keyData = NSData(base64EncodedString: key, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!
let digestLen = algorithm.digestLength
let hashResult = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
CCHmac(algorithm.HMACAlgorithm, keyData.bytes, Int(keyData.length), strData.bytes, Int(strData.length), hashResult)
let hash = NSData(bytes: hashResult, length: digestLen )
let hashString = hash.base64EncodedStringWithOptions(NSDataBase64EncodingOptions([]))
hashResult.destroy()
return hashString
}
}
最佳答案
终于成功了:)
这是我的代码,其中列出了 Azure 存储帐户中的所有表:
//
// main.swift
// Azure Storage REST Helper
//
// Created by Gaurav Mantri on 1/2/16.
//
import Foundation
let accountName = "{account-name}"
let urlString = "https://{account-name}.table.core.windows.net/Tables"
let storageUrl = NSURL(string: urlString)
let request = NSMutableURLRequest(URL: storageUrl!)
let currentDate = NSDate()
let httpFormatter = NSDateFormatter()
httpFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
httpFormatter.dateFormat = "EEE',' dd MMM yyyy HH':'mm':'ss z"
let httpTime = httpFormatter.stringFromDate(currentDate)
print(httpTime)
let signingString = "GET\n\n\n\(httpTime)\n/{account-name}/Tables"
print(signingString)
let keyString = "{account-key}"
let keyData = NSData(base64EncodedString: keyString, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!
let signingData = signingString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let length:Int = Int(CC_SHA256_DIGEST_LENGTH)
let hashResult = UnsafeMutablePointer<CUnsignedChar>.alloc(length)
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyData.bytes, Int(keyData.length), signingData.bytes, Int(signingData.length), hashResult)
print(hashResult)
let hash = NSData(bytes: hashResult, length: Int(CC_SHA256_DIGEST_LENGTH))
let hashString = hash.base64EncodedStringWithOptions(NSDataBase64EncodingOptions([]))
hashResult.destroy()
print(hashString)
request.setValue("SharedKey {account-name}:\(hashString)", forHTTPHeaderField: "Authorization")
request.setValue("0", forHTTPHeaderField: "Content-Length")
request.setValue(httpTime, forHTTPHeaderField: "x-ms-date")
request.setValue("", forHTTPHeaderField: "Date")
request.HTTPMethod = "GET"
print("comes here")
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in
if let data = data {
let datastring = NSString(data:data, encoding:NSUTF8StringEncoding)
print( datastring! )
print("comes here 1")
//print(response)
} else {
print("comes here 2")
print( error )
}
}).resume()
我做了一些事情:
- 我没有使用 UTF8 编码来获取
keyData
,而是使用base64Encoding
创建了NSData
。 - 我删除了
Content-Type
header ,因此结果以 XML 形式返回。如果您想返回 JSON 格式的数据,请指定Accept
header ,而不是Content-Type
header 。 - 您使用
SharedKey
方案创建签名,但在Authorization
header 中指定了SharedKeyLite
。我将其更改为SharedKey
。
哦,请不要评判代码并随意编辑它。我知道这不是最好的代码:)
关于ios - 从 Swift 访问 Azure 表存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34561203/