Azure blob 存储 java 生成 SAS 令牌始终抛出 sr 是强制性的。不能为空错误
Azure blob storage java generate SAS token always throw sr is mandatory. Cannot be empty error
我想使用 Java 生成 SAS 令牌,这就是我所做的:
public static String GetSASToken(String resourceUri, String keyName, String key) {
long epoch = System.currentTimeMillis() / 1000L;
int week = 60 * 30 * 1000;
String expiry = Long.toString(epoch + week);
String sasToken = null;
try {
String stringToSign = URLEncoder.encode(resourceUri, "UTF-8") + "\n" + expiry;
String signature = getHMAC256(key, stringToSign);
sasToken =
"SharedAccessSignature sr=" + URLEncoder.encode(resourceUri, "UTF-8") + "&sig="
+
URLEncoder.encode(signature, "UTF-8") + "&se=" + expiry + "&skn="
+ keyName;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return sasToken;
}
public static String getHMAC256(String key, String input) {
Mac sha256_HMAC = null;
String hash = null;
try {
sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
Encoder encoder = Base64.getEncoder();
hash = new String(encoder.encode(sha256_HMAC.doFinal(input.getBytes("UTF-8"))));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return hash;
}
这段代码只是从微软网站上复制过来的,
然后在主class:
String key = "xxxxxHh9jP1ZOTYZI/z1OCVeThsjK00sSc3TYUuiHJQ==";
String kn = "frankbucket";
String url = "https://frankbucket.blob.core.windows.net/mycontainer";
System.out.print(AzureSASTokenGenerator.GetSASToken(url, kn, key));
当我 运行 这个时,我得到了低于 SAS 的结果:
SharedAccessSignature sr=https%3A%2F%2Ffrankbucket.blob.core.windows.net%2Fmycontainer&sig=xxxj7Fgbkz5OSag%2BzFQAzBkIdd3I1J9AmFwxjcQg%3D&se=1588299503&skn=frankbucket
在Java脚本中:
var blobUri = 'https://frankbucket.blob.core.windows.net';
var token =
"SharedAccessSignature sr=https%3A%2F%2Ffrankbucket.blob.core.windows.net%2Fmycontainer&sig=ZA5fgKKny5%2BzdffvdEmy6WdsqqpoMsssssYYM9ruXgAdo0%3D&se=1588299257&skn=frankbucket";
var blobService = AzureStorage.Blob.createBlobServiceWithSas(blobUri, token);
blobService.listBlobsSegmented('mycontainer', null, function(error, results) {
当我 运行 它时,出现以下错误:
<?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:ea315aac-001e-00a0-0700-0f2e4d000000
Time:2020-04-10T06:22:18.2383162Zsr 是强制性的。不能为空
我不知道问题出在哪里,我从微软网站上获得了代码,但它不起作用。
任何人都可以向我展示这方面的工作示例吗?
希望听到您的建议。
谢谢
想了解如何使用java创建账户sas token,请参考以下代码
public void callblobRestAPIWithSas() throws NoSuchAlgorithmException, InvalidKeyException, IOException {
// 1. create account sas token
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE, -2);
String start = fmt.format(cal.getTime());
cal.add(Calendar.DATE, 4);
String expiry = fmt.format(cal.getTime());
String StorageAccountName = "blobstorage0516";
String StorageAccountKey = "";
String apiVersion="2019-07-07";
String resource ="sco";
String permissions ="rwdlac";
String service = "b";
String stringToSign = StorageAccountName + "\n" +
permissions +"\n" + // signed permissions
service+"\n" + // signed service
resource+"\n" + // signed resource type
start + "\n" + // signed start
expiry + "\n" + // signed expiry
"\n" + // signed IP
"https\n" + // signed Protocol
apiVersion+"\n"; // signed version
SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(StorageAccountKey), "HmacSHA256");
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
sha256HMAC.init(secretKey);
String signature=Base64.getEncoder().encodeToString(sha256HMAC.doFinal(stringToSign.getBytes("UTF-8")));
String sasToken = "sv=" + apiVersion +
"&ss=" + service+
"&srt=" + resource+
"&sp=" +permissions+
"&se=" + URLEncoder.encode(expiry, "UTF-8") +
"&st=" + URLEncoder.encode(start, "UTF-8") +
"&spr=https" +
"&sig=" + URLEncoder.encode(signature,"UTF-8");
//2. test the sas token
String resourceUrl="https://blobstorage0516.blob.core.windows.net/test/help.txt"; // your blob url
URL url = new URL(resourceUrl+"?"+sasToken);
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder()
.url(url)
.method("GET", null)
.build();
okhttp3.Response response = httpClient.newCall(request).execute();
if(response.isSuccessful()){
System.out.println("The blob content : "+ response.body().string());
}
}
我想使用 Java 生成 SAS 令牌,这就是我所做的:
public static String GetSASToken(String resourceUri, String keyName, String key) {
long epoch = System.currentTimeMillis() / 1000L;
int week = 60 * 30 * 1000;
String expiry = Long.toString(epoch + week);
String sasToken = null;
try {
String stringToSign = URLEncoder.encode(resourceUri, "UTF-8") + "\n" + expiry;
String signature = getHMAC256(key, stringToSign);
sasToken =
"SharedAccessSignature sr=" + URLEncoder.encode(resourceUri, "UTF-8") + "&sig="
+
URLEncoder.encode(signature, "UTF-8") + "&se=" + expiry + "&skn="
+ keyName;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return sasToken;
}
public static String getHMAC256(String key, String input) {
Mac sha256_HMAC = null;
String hash = null;
try {
sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
Encoder encoder = Base64.getEncoder();
hash = new String(encoder.encode(sha256_HMAC.doFinal(input.getBytes("UTF-8"))));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return hash;
}
这段代码只是从微软网站上复制过来的,
然后在主class:
String key = "xxxxxHh9jP1ZOTYZI/z1OCVeThsjK00sSc3TYUuiHJQ==";
String kn = "frankbucket";
String url = "https://frankbucket.blob.core.windows.net/mycontainer";
System.out.print(AzureSASTokenGenerator.GetSASToken(url, kn, key));
当我 运行 这个时,我得到了低于 SAS 的结果:
SharedAccessSignature sr=https%3A%2F%2Ffrankbucket.blob.core.windows.net%2Fmycontainer&sig=xxxj7Fgbkz5OSag%2BzFQAzBkIdd3I1J9AmFwxjcQg%3D&se=1588299503&skn=frankbucket
在Java脚本中:
var blobUri = 'https://frankbucket.blob.core.windows.net';
var token =
"SharedAccessSignature sr=https%3A%2F%2Ffrankbucket.blob.core.windows.net%2Fmycontainer&sig=ZA5fgKKny5%2BzdffvdEmy6WdsqqpoMsssssYYM9ruXgAdo0%3D&se=1588299257&skn=frankbucket";
var blobService = AzureStorage.Blob.createBlobServiceWithSas(blobUri, token);
blobService.listBlobsSegmented('mycontainer', null, function(error, results) {
当我 运行 它时,出现以下错误:
<?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:ea315aac-001e-00a0-0700-0f2e4d000000 Time:2020-04-10T06:22:18.2383162Zsr 是强制性的。不能为空
我不知道问题出在哪里,我从微软网站上获得了代码,但它不起作用。
任何人都可以向我展示这方面的工作示例吗?
希望听到您的建议。
谢谢
想了解如何使用java创建账户sas token,请参考以下代码
public void callblobRestAPIWithSas() throws NoSuchAlgorithmException, InvalidKeyException, IOException {
// 1. create account sas token
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE, -2);
String start = fmt.format(cal.getTime());
cal.add(Calendar.DATE, 4);
String expiry = fmt.format(cal.getTime());
String StorageAccountName = "blobstorage0516";
String StorageAccountKey = "";
String apiVersion="2019-07-07";
String resource ="sco";
String permissions ="rwdlac";
String service = "b";
String stringToSign = StorageAccountName + "\n" +
permissions +"\n" + // signed permissions
service+"\n" + // signed service
resource+"\n" + // signed resource type
start + "\n" + // signed start
expiry + "\n" + // signed expiry
"\n" + // signed IP
"https\n" + // signed Protocol
apiVersion+"\n"; // signed version
SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(StorageAccountKey), "HmacSHA256");
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
sha256HMAC.init(secretKey);
String signature=Base64.getEncoder().encodeToString(sha256HMAC.doFinal(stringToSign.getBytes("UTF-8")));
String sasToken = "sv=" + apiVersion +
"&ss=" + service+
"&srt=" + resource+
"&sp=" +permissions+
"&se=" + URLEncoder.encode(expiry, "UTF-8") +
"&st=" + URLEncoder.encode(start, "UTF-8") +
"&spr=https" +
"&sig=" + URLEncoder.encode(signature,"UTF-8");
//2. test the sas token
String resourceUrl="https://blobstorage0516.blob.core.windows.net/test/help.txt"; // your blob url
URL url = new URL(resourceUrl+"?"+sasToken);
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder()
.url(url)
.method("GET", null)
.build();
okhttp3.Response response = httpClient.newCall(request).execute();
if(response.isSuccessful()){
System.out.println("The blob content : "+ response.body().string());
}
}