【发布时间】:2021-09-21 18:24:09
【问题描述】:
我想使用 Apex 代码将文档上传到 Azure Blob。
我有以下 Apex 类,它将文档上传到 Azure 但给出错误
“在 HTTP 请求中找到的 MAC 签名 '' 与任何计算的签名不同”。
我不确定我在哪里弄乱了 HTTP 身份验证标头。我确实使用了来自https://stackoverflow.com 的代码。
public class AzureService {
private String storageKey;
private String storageName;
private String storageContainer;
private String storageUrl;
private String blobName;
private String requestURL;
private String fileLength;
private String formattedDate ;
private String fileType;
private String fileName;
private final string DATEFORMAT = 'EEE, dd MMM yyyy HH:mm:ss z';
private final string VERSION = '2015-12-11';
private final string BLOB_TYPE = 'BlockBlob';
public Boolean uploadBlob( Blob fileBody, Integer intFileLength, String strFileType, String strFileName)
{
Boolean isUploaded= false;
this.fileName = EncodingUtil.urlEncode(strFileName, 'UTF-8');
this.fileType = strFileType;
this.storageName = 'STORAGE_ACCOUNT';
this.storageContainer = 'CONTAINER_NAME';
this.storageKey = 'ACCESS_KEY';
this.storageUrl ='https://STORAGE_ACCOUNT.blob.core.windows.net';
this.blobName = '/'+storageName+'/'+storageContainer+'/'+fileName;
System.debug('blobName--->'+blobName);
this.requestURL = storageUrl+'/'+storageContainer+'/'+fileName;
System.debug('requestURL--->'+requestURL);
this.fileLength = String.valueof(intFileLength);
String strSharedKey = getBlobSharedKey();
try
{
this.uploadBlob(fileBody, strSharedKey);
isUploaded = true;
}catch(Exception exp)
{
System.debug('Exception occur while uploading the Blob-->'+exp.getMessage());
isUploaded = false;
}
return isUploaded;
}
public String getBlobSharedKey()
{
System.debug('getBlobSharedKey--->Start');
String sharedKey;
String signature;
Datetime dt = Datetime.now();
this.formattedDate = dt.formatGMT(DATEFORMAT);
String stringToSign = 'PUT\n\n\n'+fileLength+'\n\n'+fileType+'\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:'+formattedDate+'\nx-ms-version:2015-12-11\n'+blobName;
System.debug('stringToSign--->'+stringToSign);
Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
Blob data = Crypto.generateMac('hmacSHA256', Blob.valueOf(stringToSign), unicodeKey);
signature = EncodingUtil.base64Encode(data);
sharedKey = 'SharedKey '+storageName+':' + signature;
return sharedKey;
}
public void uploadBlob(Blob fileBody, String sharedKey)
{
HttpRequest req = new HttpRequest();
req.setMethod('PUT');
req.setHeader('x-ms-blob-type', BLOB_TYPE);
req.setHeader('x-ms-version', VERSION);
req.setHeader('x-ms-date', formattedDate);
req.setHeader('Authorization', sharedKey);
req.setHeader('Content-Type', fileType);
req.setHeader('Content-Length', fileLength);
req.setEndpoint(this.requestURL);
req.setBodyAsBlob(fileBody);
Http http = new Http();
HTTPResponse res = http.send(req);
// in the response body you have your blob
System.debug('Response Body--->'+res.getBody());
System.debug('Status--->'+res.getStatus());
}
}
【问题讨论】:
-
在您的错误响应中,您应该看到 Azure 存储服务为
stringToSign使用的值。将其与您正在计算的stringToSign的值进行比较。它们都应该完全匹配。 -
男人!你太棒了。非常感谢。我输入 Filelenght 为 168,实际上是 126。非常感谢!
标签: azure azure-blob-storage apex