简体   繁体   English

无法从 Java 下载 Azure blob

[英]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.

相关问题 从Azure Blob存储下载Blob列表 - Download list of blobs from Azure Blob Storage 如何使用基于证书的身份验证创建Azure Blob,使用Java从文件中下载文件 - How to create Azure blob with certificate based authentication n download file from that using java 从 Azure blob 存储下载所有文件,将其压缩并在 JAVA 中上传 zip 文件 - Download all the files from Azure blob storage , zip it and upload the zip file in JAVA 将Azure存储中的Blob(文本文件)以UTF8格式下载到内存中吗? - Download blob (text file) from Azure storage to memory as UTF8? 无法从 Azure 存储帐户中删除 blob - Azure Function (Java) - Not able to delete blob from Azure storage Account - Azure Function (Java) 如何在 Azure 中获取 blob 下载进度 blob 下载 - How to get blob Download Progress in Azure blob download 通过Java从MySQL数据库下载BLOB数据 - Download BLOB data from MySQL database via Java Azure 构建管道无法从 azure 工件下载依赖项, - Azure build pipeline unable to download the dependences from azure artifact, Basic blob download fails using com.azure.storage.blob package with java.nio.channels.ClosedChannelException in Scala - Basic blob download fails using com.azure.storage.blob package with java.nio.channels.ClosedChannelException in Scala 如何使用Java中的Azure函数使用Blob存储 - How can i use blob storage from an azure function in Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM