我正在创建应用程序,我正在通过 Java 服务在 Azure 存储帐户中上传和下载文件。当我上传名称中没有空格的文件(例如:"图像.png"(时,程序成功地向我返回了令牌。
但是当我尝试在上传或下载文件名时获取令牌时,文件名之间有空格,例如"新图像.png",它会在特定行出现错误。
我的代码是:
CloudFile cloudFile = directory.getFileReference(fileNameWithExtension);
String tokenKey = testFileSAS(share, cloudFile);
System.out.println(cloudFile.toString());
cloudFile.downloadToFile(DownloadTo);
其中,获取令牌的代码是:
@Test
public String testFileSAS(CloudFileShare share, CloudFile file) throws InvalidKeyException, IllegalArgumentException, StorageException, URISyntaxException, InterruptedException {
SharedAccessFilePolicy policy = createSharedAccessPolicy(
EnumSet.of(SharedAccessFilePermissions.READ,
SharedAccessFilePermissions.LIST,
SharedAccessFilePermissions.WRITE),
100);
FileSharePermissions perms = new FileSharePermissions();
perms.getSharedAccessPolicies().put("readperm", policy);
share.uploadPermissions(perms);
CloudFile sasFile = new CloudFile(new URI(file.getUri().toString()
+ "?" + file.generateSharedAccessSignature(null, "readperm")));
System.out.println("sasFile==========="+sasFile.getName());
sasFile.download(new ByteArrayOutputStream());
CloudFile fileFromUri = new CloudFile(PathUtility.addToQuery(file.getStorageUri(),
file.generateSharedAccessSignature(null, "readperm")));
assertEquals(StorageCredentialsSharedAccessSignature.class.toString(),
fileFromUri.getServiceClient().getCredentials().getClass().toString());
StorageCredentials creds = new StorageCredentialsSharedAccessSignature(
file.generateSharedAccessSignature(policy, null, null));
System.out.println("Generated SAS token is : " + file.generateSharedAccessSignature(policy, null, null));
String token = file.generateSharedAccessSignature(policy, null, null);
CloudFileClient client = new CloudFileClient(sasFile.getServiceClient().getStorageUri(), creds);
CloudFile fileFromClient = client.getShareReference(file.getShare().getName()).getRootDirectoryReference()
.getFileReference(file.getName());
assertEquals(StorageCredentialsSharedAccessSignature.class.toString(),
fileFromClient.getServiceClient().getCredentials().getClass().toString());
assertEquals(client, fileFromClient.getServiceClient());
return token;
}
我在这一行得到错误:
sasFile.download(new ByteArrayOutputStream());
我认为这是因为当文件名中有空格时,它会用 %20 代替空格,因此,它无法获取文件并给出错误。
我应该怎么做才能执行所需的操作?
我尝试成功重现您的问题,并通过 Fiddler 获取错误信息,如下所示。
<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:237ce8e7-001a-000d-57df-e4c9be000000 Time:2017-06-14T07:28:17.0520478Z
</Message>
<AuthenticationErrorDetail>
Signed expiry must be specified in signature or SAS identifier
</AuthenticationErrorDetail>
</Error>
该问题是由不正确的 SAS 令牌引起的,而不是由包含空格的文件名引起的。所以我在下面更改了您的代码,使其在设置策略的到期时间时正常工作,尽管我不知道您的方法的实现createSharedAccessPolicy
.
SharedAccessFilePolicy policy = new SharedAccessFilePolicy();
policy.setPermissions(EnumSet.of(SharedAccessFilePermissions.READ,
SharedAccessFilePermissions.LIST,
SharedAccessFilePermissions.WRITE));
// Set expiry time for policy, and then it works.
policy.setSharedAccessExpiryTime(new Date(new Date().getTime()+3600));
FileSharePermissions perms = new FileSharePermissions();
perms.getSharedAccessPolicies().put("readperm", policy);
share.uploadPermissions(perms);
String uri = file.getUri().toString()
+ "?" + file.generateSharedAccessSignature(null, "readperm");
CloudFile sasFile = new CloudFile(new URI(uri));
System.out.println("sasFile==========="+sasFile.getName());
sasFile.download(new ByteArrayOutputStream());