[英]Unable to download Azure blob from Java
This is a rather strange issue.这是一个比较奇怪的问题。 I need to generate a signed url that can be shared with others for downloading the file within a certain time limit.我需要生成一个签名的 url,可以与其他人共享,以便在特定时限内下载文件。 Obviously, since I am saying signed, you should not require any prior permissions to download.显然,既然我说的是签名,那么您不应该需要任何事先的许可来下载。 Following is the code I am using to upload and download以下是我用来上传和下载的代码
private final BlobSasPermission blobSasPermission = new BlobSasPermission()
.setReadPermission(true);
public String uploadAndGenerateSignedUrl(String filePath, String uploadPath) {
BlobClient blobClient = containerClient.getBlobClient(uploadPath);
blobClient.uploadFromFile(filePath);
BlockBlobClient blockBlobClient = blobClient.getBlockBlobClient();
BlobServiceSasSignatureValues blobServiceSasSignatureValues = new BlobServiceSasSignatureValues(
OffsetDateTime.now().plusMinutes(azureConfiguration.getExpiryMin()), blobSasPermission);
return blockBlobClient.getBlobUrl() + "?" + blockBlobClient
.generateSas(blobServiceSasSignatureValues);
}
public void downloadFromUrl(String signedUrl, File file) throws IOException {
OkHttpClient client = SharedClient.getNewSharedClientBuilder().build();
Request request = new Request.Builder()
.url(signedUrl)
.build();
okhttp3.Response response = client.newCall(request).execute();
InputStream inputStream = response.body().byteStream();
FileUtils.copyInputStreamToFile(inputStream, file);
}
Now, when I open the generated url in the browser, the file is successfully downloaded.现在,当我在浏览器中打开生成的 url 时,文件已成功下载。 Similarly, running the GET in PostMan for this url, works fine.同样,在 PostMan 中为这个 url 运行 GET,工作正常。 However, when I send the same url to the download method, it fails with error 403 stating Server failed to authenticate the request.但是,当我将相同的 url 发送到下载方法时,它失败并显示错误 403,说明服务器无法对请求进行身份验证。 I am clueless about the reason for this.我对此一无所知。 I tried adding both http and https protocols to signed url but that also did not help.我尝试将 http 和 https 协议添加到签名的 url 中,但这也没有帮助。
Edit:编辑:
Adding the error message添加错误信息Response{protocol=http/1.1, code=403, message=Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature., url=https://{account}.blob.core.windows.net/{container}/MDConnector/MDTest/Test_16269425/2021-07-24/1627125196450/NormalFile.md?sv=2019-07-07&se=2021-07-24T12:13:18Z&sr=b&sp=r&sig=BoTaZ9iEA8Cdcbscf6zpWTol32+52rfVyLNDMBlLr1Q=}
I'm able to reproduce this issue.我能够重现这个问题。 Essentially the issue is coming because of +
sign in your SAS token signature.本质上,问题是由于+
登录您的 SAS 令牌签名而出现的。 When a URL is created, +
sign is interpreted as a space and because of that your authorization is failing.创建 URL 时, +
号被解释为空格,因此您的授权失败。
What you have to do is URL encode your SAS token.您需要做的是对您的 SAS 令牌进行 URL 编码。 Once you do that, your request should work just fine.一旦你这样做了,你的请求应该可以正常工作。 Please see the sample code below:请参阅下面的示例代码:
package com.company;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws IOException {
String url = "https://account.blob.core.windows.net/container/blob.png";
String sasToken = "sv=2020-04-08&st=2021-07-24T14:33:27Z&se=2021-07-31T14:33:00Z&sr=b&sp=rac&sig=QytPc/+0z/eHd+u4WO0HGOFDOZjVfB+vbQdbR6FFrl4=";//Notice the "+" sign in SAS token.
sasToken = URLEncoder.encode(sasToken, StandardCharsets.UTF_8.toString());
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url+"?"+ sasToken).build();
okhttp3.Response response = client.newCall(request).execute();
InputStream inputStream = response.body().byteStream();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.