【问题标题】:Azure File share SAS token signature not generating as expected, How do one generate signature for file object to match the one generated in portal?Azure 文件共享 SAS 令牌签名未按预期生成,如何为文件对象生成签名以匹配门户中生成的签名?
【发布时间】:2021-03-05 20:10:55
【问题描述】:

我正在尝试以编程方式为 SAS 令牌创建一个签名,当用户选择几个选项时,该签名应该与 azure 门户中生成的签名相匹配。但是,文档非常混乱,并不能指导您实现操作所需的内容。我在 azure 文件共享中有一个文件,我想通过生成 SAS 令牌并对其进行签名来访问它。我可以通过在 Azure 门户中选择适当的选项并访问文件来轻松地做到这一点,但我想以编程方式完成确切的事情。我用 java 试过,但结果 SAS 令牌签名不匹配。请帮帮我。

下面是我通过 Azure 门户生成的 SAS 令牌:

?sv=2019-12-12&ss=f&srt=o&sp=r&se=2020-11-23T12:20:39Z&st=2020-11-23T04:20:39Z&spr=https&sig=XI%2FlSZSXp54XVwk2G%2F23j%2FjqsrojVqJoAonh6gdaAPk%3D

在azure portal中为上述sas token选择的对应选项如下图所示

使用的密钥是key1,如下:

l1wxekiJj9IcTw350w5c1MtVfYVP3qcz3zdxzCCp+YVaXqs9faOJfl/Z07AoLDnsnyn+POGjxjcFy3EF9g/r9Q==

我尝试的是为以下选项(要签名的字符串)生成签名,该签名取自 azure 门户生成的 SAS 令牌并使用上面的 key1。

sv=2019-12-12&ss=f&srt=o&sp=r&se=2020-11-23T12:20:39Z&st=2020-11-23T04:20:39Z&spr=https

下面是我的java代码,它为上面的字符串生成签名

import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
public class GenerateSAS {
    public static void main(String[] args) throws Exception{
        Mac sha256_HMAC = null;
        String hash = null;
        String input="sv=2019-12-12&ss=f&srt=o&sp=r&se=2020-11-23T12:20:39Z&st=2020-11-23T04:20:39Z&spr=https";
        input=URLEncoder.encode(input, "UTF-8");
        String key="l1wxekiJj9IcTw350w5c1MtVfYVP3qcz3zdxzCCp+YVaXqs9faOJfl/Z07AoLDnsnyn+POGjxjcFy3EF9g/r9Q==";
        sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        hash = new String(Base64.encodeBase64(sha256_HMAC.doFinal(input.getBytes("UTF-8"))));
        System.out.println(hash);
    }

上面的代码生成的签名是MK/uu+NlURscoX1dymzipRN/Jb4aXyVzfbIVBz8l02M=,这不等于在azure门户中生成的签名是XI%2FlSZSXp54XVwk2G%2F23j%2FjqsrojVqJoAonh6gdaAPk%3D

请帮助我正确生成签名,这将帮助我将其附加到 SAS 令牌以进行文件对象访问。

【问题讨论】:

    标签: java azure azure-storage signature


    【解决方案1】:

    如果要创建 sas 令牌来访问 Azure 文件服务资源,签名字符串应如下所示。更多详情请参考here

    StringToSign = accountname + "\n" +  
        signedpermissions + "\n" +  
        signedservice + "\n" +  
        signedresourcetype + "\n" +  
        signedstart + "\n" +  
        signedexpiry + "\n" +  
        signedIP + "\n" +  
        signedProtocol + "\n" +  
        signedversion + "\n"  
    

    例如

     public static void createSasToken(){
    
        String accountName = "accountName";
        String key = "accountKey";
        String resourceUrl = "https://"+accountName+".file.core.windows.net/fileShare/fileName";
        /**
         * please note the date formate should be  ISO 8601 UTC formats 
         * for further information, please refer to https://docs.microsoft.com/en-us/rest/api/storageservices/formatting-datetime-values
        */
        String start = "startTime";
        String expiry = "expiry";
        String apiVersion = "2019-12-12";
    
        String stringToSign = accountName + "\n" +
                    "r\n" +
                    "f\n" +
                    "o\n" +
                    start + "\n" +
                    expiry + "\n" +
                    "\n" +
                    "https\n" +
                    apiVersion +"\n";
    
        String signature = getHMAC256(key, stringToSign);
    
        try{
    
            String sasToken = "sv=" + azureApiVersion +
                "&ss=f" +
                "&srt=o" +
                "&sp=r" +
                "&se=" +URLEncoder.encode(expiry, "UTF-8") +
                "&st=" + URLEncoder.encode(start, "UTF-8") +
                "&spr=https" +
                "&sig=" + URLEncoder.encode(signature, "UTF-8");
    
        System.out.println(resourceUrl+"?"+sasToken);
    
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    
    private static String getHMAC256(String accountKey, String signStr) {
        String signature = null;
        try {
            SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(accountKey), "HmacSHA256");
            Mac sha256HMAC = Mac.getInstance("HmacSHA256");
            sha256HMAC.init(secretKey);
            signature = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(signStr.getBytes("UTF-8")));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return signature;
    }
    

    【讨论】:

    • 谢谢吉姆,我非常感谢你。我指的是“创建服务 sas”,但正确的文档是“创建帐户 sas”。非常感谢您帮助我。
    猜你喜欢
    • 2020-05-29
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 2022-01-04
    • 2020-09-04
    • 2022-06-17
    • 2019-10-10
    • 1970-01-01
    相关资源
    最近更新 更多