使用APEX生成Azure Blob SAS令牌

问题描述 投票:0回答:1

根据Azure文档,我想生成SAS令牌,以下是BLOB的示例。我仍然遇到错误。您能否确定我在做什么错。

StringToSign = signedpermissions + "\n" +  
               signedstart + "\n" +  
               signedexpiry + "\n" +  
               canonicalizedresource + "\n" +  
               signedidentifier + "\n" +  
               signedIP + "\n" +  
               signedProtocol + "\n" +  
               signedversion + "\n" +  
               rscc + "\n" +  
               rscd + "\n" +  
               rsce + "\n" +  
               rscl + "\n" +  
               rsct

URL =https://myaccount.blob.core.windows.net/mycontainer/test.txtcanonicalizedresource =“ /blob/myaccount/mycontainer/test.txt

我收到以下错误

<?xml version="1.0" encoding="utf-8"?>
<Error>
    <Code>AuthenticationFailed</Code>
    <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:4b1d1c59-c01e-0052-0197-ffe09f000000
Time:2020-03-21T15:44:34.2757923Z</Message>
    <AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
</Error>  

以下是我的代码

public void getSasToken() {

    this.storageName = 'zaindevtesting';
    this.storageContainer = 'zaindevblob';
    this.storageKey = 'xxxxxxZFQ==';
    this.storageUrl ='https://zaindevtesting.blob.core.windows.net';

    Datetime sasExpiry = Datetime.now();
    sasExpiry.addMinutes(15);
    Datetime sasStart = Datetime.now();
    sasStart.addMinutes(-5);


    string signedpermissions = 'rwdlac';
    String signedstart = sasStart.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
    string signedexpiry = sasExpiry.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
    string signedservice = 'b';
    String canonicalizedresource = '/blob/zaindevtesting/zaindevblob/test.txt';
    string signedidentifier = '';
    string signedIP = '';
    string signedProtocol = 'https';
    string signedversion = '2015-04-05';
    string rscc='';
    string rscd='';
    string rsce='';
    string rscl='';
    string rsct='';


    string stringToSign =signedpermissions + '\n' +  
               signedstart + '\n' +  
               signedexpiry + '\n' +  
               canonicalizedresource + '\n' +  
               signedidentifier + '\n' +  
               signedIP + '\n' +  
               signedProtocol + '\n' +  
               signedversion + '\n' +  
               rscc + '\n' +  
               rscd + '\n' +  
               rsce + '\n' +  
               rscl + '\n' +  
               rsct;

    string signedExpiryEncode = EncodingUtil.urlEncode(signedexpiry, 'UTF-8'); 
    string signedStartEncode = EncodingUtil.urlEncode(signedstart, 'UTF-8'); 
    String sasToken = '';
    Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
    Blob data = Crypto.generateMac('HMACSHA256', Blob.valueOf(stringToSign), unicodeKey);
    sasToken = EncodingUtil.base64Encode(data);
    String sasTokenString= '?sv=' + signedversion + '&se=' + signedexpiry +'&st='+signedstart+'&sr='+signedservice+'&sp=' + signedpermissions + '&sig=' + sasToken;

    string sasURL = 'https://zaindevtesting.blob.core.windows.net/test.txt'+sasTokenString;
    System.debug('sasURL--->'+sasURL);
    System.debug(sasTokenString);
   // return sasToken;
}

此代码通过SAS链接生成

https://zaindevtesting.blob.core.windows.net/test.txt??sv=2017-11-09&st=2020-03-21T15%3A44%3A07Z&se=2020-03-21T15%3A44%3A07Z&sr=b&sp=rwdc&sig=eJVbGWI4rcyjggOYAE308ilXEA/zAsFYbuNi24IZhX4=

azure salesforce blob apex
1个回答
0
投票

请尝试以下代码:

public void generateSASToken()
{
    string storageName = 'zaindevtesting';
    string storageContainer = 'zaindevblob';
    string storageKey = 'xxxx==';
    string storageUrl ='https://zaindevtesting.blob.core.windows.net';

    Datetime sasExpiry = Datetime.now();
    sasExpiry = sasExpiry.addMinutes(15);
    Datetime sasStart = Datetime.now();
    sasStart = sasStart.addMinutes(-5);


    string signedpermissions = 'r';
    String signedstart = sasStart.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
    string signedexpiry = sasExpiry.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
    string signedservice = 'b';
    String canonicalizedresource = '/blob/zaindevtesting/zaindevblob/test.txt';
    string signedidentifier = '';
    string signedIP = '';
    string signedProtocol = '';
    string signedversion = '2015-04-05';
    string rscc='';
    string rscd='';
    string rsce='';
    string rscl='';
    string rsct='';


    string stringToSign =signedpermissions + '\n' +  
        signedstart + '\n' +  
        signedexpiry + '\n' +  
        canonicalizedresource + '\n' +  
        signedidentifier + '\n' +  
        signedIP + '\n' +  
        signedProtocol + '\n' +  
        signedversion + '\n' +  
        rscc + '\n' +  
        rscd + '\n' +  
        rsce + '\n' +  
        rscl + '\n' +  
        rsct;
    System.debug('stringToSign--->'+stringToSign);
    string signedExpiryEncode = EncodingUtil.urlEncode(signedexpiry, 'UTF-8'); 
    string signedStartEncode = EncodingUtil.urlEncode(signedstart, 'UTF-8'); 
    String sasToken = '';
    Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
    Blob data = Crypto.generateMac('HMACSHA256', Blob.valueOf(stringToSign), unicodeKey);
    sasToken = EncodingUtil.base64Encode(data);
    sasToken = EncodingUtil.urlEncode(sasToken, 'UTF-8');        
    String sasTokenString= '?sv=' + signedversion + '&se=' + signedexpiry +'&st='+signedstart+'&sr='+signedservice+'&sp=' + signedpermissions + '&sig=' + sasToken;

    string sasURL = 'https://zaindevtesting.blob.core.windows.net/zaindevblob/test.txt'+sasTokenString;
    System.debug('sasURL--->'+sasURL);
    System.debug(sasTokenString);
    // return sasToken;
}

我刚刚用您的存储帐户密钥进行了尝试,并且能够下载Blob。

发现您的代码存在以下问题:

  • 权限必须按特定顺序。您使用的string signedpermissions = 'rwdlac';顺序不正确。我刚刚指定了read权限。
  • 签名协议在stringToString中指定,但未包含在SAS URL中。我从两个地方都省略了。
  • SAS令牌未进行URL编码。
  • 您为zaindevtesting.blob.core.windows.net/zaindevblob/test.txt URL生成了SAS令牌,但忘记了在最终URL中包含Blob容器名称。
© www.soinside.com 2019 - 2024. All rights reserved.