如何用dart语言生成用于blob存储的SAS令牌

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

我目前正在尝试使用 dart 语言为 blob 文件生成 SAS 令牌。我也参考了Python代码。在 python 中,generate_sas_token() 函数需要用于 azure blob 存储的策略 id。哪里可以得到这个

这是我所拥有的信息,或者除了python中的generate_sas_token() SDK之外还有其他方法可以生成吗?原因是我想仅通过 dart 创建 SAS 令牌。所以我需要一个流程或方法来生成 SAS。

提前致谢

import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:intl/intl.dart';

String encode_signature(String signature){
  return signature.replaceAll(':', '%3A');
}

String generateSasToken(String accountName, String accountKey, String containerName, String blobName, int expiryHours) {
  var ttl = DateTime.now().add(Duration(hours: expiryHours)).millisecondsSinceEpoch ~/ 1000;
  
  var stringToSign = "r\n${DateFormat("yyyy-MM-ddTHH:mm:ssZ").format(DateTime.now().toUtc())}\n${DateFormat("yyyy-MM-ddTHH:mm:ssZ").format(DateTime.now().add(Duration(hours: expiryHours)).toUtc())}\n/$accountName/$containerName/$blobName\n\n\n\n\n\n\n";
  
  var hmacSha256 = Hmac(sha256, base64.decode(accountKey));
  var signature = base64.encode(hmacSha256.convert(utf8.encode(stringToSign)).bytes);
  
  var queryParams = {
    'sp': 'r',
    'st': DateFormat("yyyy-MM-ddTHH:mm:ssZ").format(DateTime.now().toUtc()),
    'se': DateFormat("yyyy-MM-ddTHH:mm:ssZ").format(DateTime.now().add(Duration(hours: expiryHours)).toUtc()),
    'sv': '2022-11-02',
    'sr': 'b',
    'sig': encode_signature(signature),//Uri.encodeComponent(signature).replaceAll('%3A', ':'), // Encode the signature component
  };

  var queryString = Uri(queryParameters: queryParams).query;

  return queryString;
}

void main() {
  var accountName = "account_name";
  var accountKey = "accountkey";
  var containerName = "azure-webjobs-hosts";
  var blobName = "0_12d6fa4202ac42bdbc33923c413c68ff_1.json";
  var expiryHours = 168;

  var sasToken = generateSasToken(accountName, accountKey, containerName, blobName, expiryHours);
  print(sasToken);
}

这是我现在运行的代码,我能够得到,但唯一的问题是 这是在azure门户中生成的SAS -

sp=r&st=2024-03-11T06:25:18Z&se=2024-03-11T14:25:18Z&sv=2022-11-02&sr=b&sig=sMX853JrU%2BkgAGgKTXS1XQRvFoh6%2BQQ3jNWRnG8LWVI%3D

这是由上面的代码生成的 -

sp=r&st=2024-03-14T11%3A56%3A00&se=2024-03-21T11%3A56%3A00&sv=2022-11-02&sr=b&sig=jPsFzl2RoTJNGbMNg%252FwcT1oi%252FyIIBjFJeps1pJyMC GC%253D

我得到的是“%3A”,而不是冒号“:”。即使我使用了替换所有功能。 可能是什么问题?

azure azure-blob-storage azure-storage azure-storage-account shared-access-signatures
1个回答
0
投票

下面的代码 dart 生成用于访问 Azure Blob 存储资源的共享访问签名 (SAS) 令牌。 SAS 令牌提供对存储帐户中资源的受限访问,具有指定的权限和时间限制。

生成SasToken方法:

它根据提供的参数(例如resourceUri、key、permissions、sr和expiryHours)生成SAS令牌。

import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:crypto/crypto.dart';

class SasTokenGenerator {
  String generateSasToken({
    required String resourceUri,
    required String key,
    required String permissions,
    required String sr, // Added parameter for the resource type
    int expiryHours = 24,
  }) {
    DateTime startTime = DateTime.now(); // Adjusting start time by 5 minutes for clock skew
    DateTime expiry = startTime.add(Duration(hours: expiryHours));
    String formattedStartTime = DateFormat("yyyy-MM-ddTHH:mm:ss'Z'").format(startTime);
    String formattedExpiry = DateFormat("yyyy-MM-ddTHH:mm:ss'Z'").format(expiry);

    String stringToSign = 'sp=$permissions\nst=$formattedStartTime\nse=$formattedExpiry\nspr=https\nsv=2022-11-02\nsr=$sr\n$resourceUri'; // Include sr parameter
    String signature = _generateSignature(stringToSign, key);

    return 'sp=$permissions&st=$formattedStartTime&se=$formattedExpiry&spr=https&sv=2022-11-02&sr=$sr&sig=$signature'; // Include sr parameter
  }

  String _generateSignature(String input, String key) {
    var keyBytes = utf8.encode(key);
    var inputBytes = utf8.encode(input);
    var hmacSha256 = Hmac(sha256, keyBytes);
    var digest = hmacSha256.convert(inputBytes);
    return Uri.encodeComponent(base64.encode(digest.bytes));
  }
}

void main() {
  String resourceUri = "https://account_name.blob.core.windows.net/containerName/example.txt";
  String key = "accountkey";
  String permissions = "r"; // r for read, w for write, d for delete, etc.
  String sr = "b"; // Specify the resource type: b for Blob service, c for Container service, etc.
  int expiryHours = 24; // Expiry duration in hours

  SasTokenGenerator generator = SasTokenGenerator();
  String sasToken = generator.generateSasToken(
    resourceUri: resourceUri,
    key: key,
    permissions: permissions,
    sr: sr, // Pass sr parameter
    expiryHours: expiryHours,
  );

  print('Generated SAS Token: $sasToken');
}

输出: enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.