Azure Blob存储:上传时设置Blob过期及SAS Token生成问题
问题解决:Blob自动过期设置与SAS Token生成修复
一、设置Blob自动过期时间
要让Blob在1-2分钟后自动删除,直接在上传阶段通过BlobRequestConditions指定过期时间即可,Azure存储服务会在到期后自动清理该Blob:
在构建BlobParallelUploadOptions时,给BlobRequestConditions设置expiresOn参数:
OffsetDateTime expiryTime = OffsetDateTime.now().plusMinutes(1); // 1分钟后过期 BlobRequestConditions requestConditions = new BlobRequestConditions() .setExpiresOn(expiryTime);
将这个条件传入BlobParallelUploadOptions的setRequestConditions方法,上传完成后Blob就会按指定时间自动过期删除。
二、修复SAS Token生成的NullPointerException
异常原因
你当前使用BlobContainerClient.generateSas生成容器级SAS,但该方法依赖存储账户的共享密钥(SharedKeyCredentials)完成签名。如果你的connectionString不是包含账户名称和密钥的完整连接字符串(比如用的是SAS连接字符串),就会触发空指针异常。另外,你实际需要的是单个Blob的访问SAS,用容器级权限也不符合最小权限原则。
正确实现方式
改用BlobClient.generateSas生成Blob级别的SAS Token,使用BlobSasPermission配置Blob的访问权限,同时确保connectionString是包含账户名和密钥的完整格式(格式示例:DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=xxx;EndpointSuffix=core.windows.net)。
修正后的SAS生成代码:
// 配置Blob级别的权限,按需调整 BlobSasPermission blobSasPermission = new BlobSasPermission() .setReadPermission(true) .setWritePermission(false) .setDeletePermission(false); OffsetDateTime sasExpiryTime = OffsetDateTime.now().plusMinutes(1); // SAS有效期与Blob过期时间一致 BlobServiceSasSignatureValues sasValues = new BlobServiceSasSignatureValues(sasExpiryTime, blobSasPermission); // 生成Blob级SAS Token String sasToken = blobClient.generateSas(sasValues);
完整修正后的代码
public String storeFile(MultipartFile file) { try { BlobContainerClient blobContainerClient = new BlobContainerClientBuilder() .connectionString(connectionString) .containerName(containerName) .buildClient(); BlobClient blobClient = blobContainerClient.getBlobClient(file.getOriginalFilename()); // 设置Blob过期时间(1分钟后自动删除) OffsetDateTime blobExpiryTime = OffsetDateTime.now().plusMinutes(1); BlobRequestConditions requestConditions = new BlobRequestConditions() .setExpiresOn(blobExpiryTime); // 配置Blob HTTP头 BlobHttpHeaders headers = new BlobHttpHeaders().setContentType(MediaType.APPLICATION_PDF_VALUE); BinaryData data = BinaryData.fromStream(file.getInputStream(), file.getSize()); BlobParallelUploadOptions uploadOptions = new BlobParallelUploadOptions(data) .setRequestConditions(requestConditions) .setHeaders(headers); // 上传Blob blobClient.uploadWithResponse(uploadOptions, null, Context.NONE); // 生成Blob级SAS Token BlobSasPermission sasPermission = new BlobSasPermission() .setReadPermission(true); // 仅开放读权限,按需调整 BlobServiceSasSignatureValues sasValues = new BlobServiceSasSignatureValues(blobExpiryTime, sasPermission); String sasToken = blobClient.generateSas(sasValues); // 拼接完整的可访问URL String blobUrl = blobClient.getBlobUrl(); return blobUrl + "?" + sasToken; } catch (Exception e) { e.printStackTrace(); return null; } }
额外注意事项
- 确保
connectionString是包含账户名和密钥的完整连接字符串,不能是SAS连接字符串,否则generateSas方法会因缺少签名密钥而失败。 - SAS Token的有效期建议与Blob的过期时间保持一致,避免过期后仍有可用的访问链接。
- 权限配置遵循最小权限原则,比如仅开放读权限,不要赋予不必要的写/删权限。
内容的提问来源于stack exchange,提问作者Maifee Ul Asad
相关产品推荐
相关产品推荐

