Создание токена SAS в Java для загрузки файла в контейнер хранилища данных Azure - PullRequest
0 голосов
/ 06 декабря 2018

Попытка сгенерировать токен SAS для доступа к определенным файлам в учетной записи хранения.Я использую методы, перечисленные здесь:

https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token

Теперь у меня проблема в том, что я не могу, на всю жизнь, заставить работать строку sasToken.Если я сгенерирую токен через Портал (подпись общего доступа в учетной записи хранения), я смогу получить доступ к этим файлам через URL с помощью предоставленного токена.

Однако мне еще не удалось сгенерировать токен SAS программночерез Java, используя методы, которые я связал выше.Я думаю, что моя проблема заключается в шифровании StringToSign.Я следовал этому примеру при построении строки для шифрования:

https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas

Все мои усилия привели к:

<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>

или

<AuthenticationErrorDetail>Signature did not match. String to sign used was <insert string details here>

Глядя на сгенерированный Порталом sasToken, который работает для меня:

? Sv = 2017-11-09 & ss = f & srt = o & sp = r & se = 2018-12-06T22: 15: 20Z & st = 2018-12-06T14: 15: 20Z & spr = https & sig =% 2Bi1TWv5D80U% 2BoaIeoBh1wjaO1p4xVFx4nRZt% 2FzwiszY% 3D

Похоже, мне нужна строка, подобная этой:

            String stringToSign = accountName + "\n" +
                "r\n" +
                "f\n" +
                "o\n" +
                URLEncoder.encode(start, "UTF-8") + "\n" +
                URLEncoder.encode(expiry, "UTF-8") + "\n" +
                "\n" +
                "https\n" +
                azureApiVersion;

имя 1025 * * 1025Azure и start / expiry - это начальная и конечная строки (т.е. 2018-12-06T22: 15: 20Z), а azureApiVersion имеет значение «2017-11-09».

Затем я пытаюсь вернуть токен послеконструируем строку следующим образом:

        String signature = getHMAC256(key, stringToSign);
        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");

Я пробовал кодирование URL, а не URL, а также даты начала / истечения срока действия, на случай, если это испортит ситуацию.Чего мне не хватает?

1 Ответ

0 голосов
/ 11 декабря 2018

Три точки для исправления

  1. getHMAC256 проблема метода, как упомянуто @ Gaurav

  2. Не кодировать expiry и start в stringToSign или подпись не будет совпадать.Поскольку закодированная часть в url будет декодирована службой хранилища Azure для вычисления ожидаемой подписи.

  3. В stringToSign, пропустите один \n после azureApiVersion.

Вот полный пример.

 public static void GetFileSAS(){

    String accountName = "accountName";
    String key = "accountKey";
    String resourceUrl = "https://"+accountName+".file.core.windows.net/fileShare/fileName";

    String start = "startTime";
    String expiry = "expiry";
    String azureApiVersion = "2017-11-09";

    String stringToSign = accountName + "\n" +
                "r\n" +
                "f\n" +
                "o\n" +
                start + "\n" +
                expiry + "\n" +
                "\n" +
                "https\n" +
                azureApiVersion+"\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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...