Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sdk/storage/azure-storage-blob/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "java",
"TagPrefix": "java/storage/azure-storage-blob",
"Tag": "java/storage/azure-storage-blob_098e26235c"
"Tag": "java/storage/azure-storage-blob_26d22d7fb8"
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public class BlobSasImplUtil {

private String encryptionScope;

private String delegatedUserObjectId;

/**
* Creates a new {@link BlobSasImplUtil} with the specified parameters
*
Expand Down Expand Up @@ -140,6 +142,7 @@ public BlobSasImplUtil(BlobServiceSasSignatureValues sasValues, String container
this.authorizedAadObjectId = sasValues.getPreauthorizedAgentObjectId();
this.correlationId = sasValues.getCorrelationId();
this.encryptionScope = encryptionScope;
this.delegatedUserObjectId = sasValues.getDelegatedUserObjectId();
}

/**
Expand Down Expand Up @@ -262,6 +265,8 @@ private String encode(UserDelegationKey userDelegationKey, String signature) {
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_PREAUTHORIZED_AGENT_OBJECT_ID,
this.authorizedAadObjectId);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_CORRELATION_ID, this.correlationId);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_DELEGATED_USER_OBJECT_ID,
this.delegatedUserObjectId);
}
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SIGNED_RESOURCE, this.resource);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SIGNED_PERMISSIONS, this.permissions);
Expand Down Expand Up @@ -438,7 +443,7 @@ private String stringToSign(final UserDelegationKey key, String canonicalName) {
this.contentEncoding == null ? "" : this.contentEncoding,
this.contentLanguage == null ? "" : this.contentLanguage,
this.contentType == null ? "" : this.contentType);
} else {
} else if (VERSION.compareTo(BlobServiceVersion.V2025_11_05.getVersion()) <= 0) {
return String.join("\n", this.permissions == null ? "" : this.permissions,
this.startTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.startTime),
this.expiryTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
Expand All @@ -462,6 +467,30 @@ private String stringToSign(final UserDelegationKey key, String canonicalName) {
this.contentEncoding == null ? "" : this.contentEncoding,
this.contentLanguage == null ? "" : this.contentLanguage,
this.contentType == null ? "" : this.contentType);
} else {
return String.join("\n", this.permissions == null ? "" : this.permissions,
this.startTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.startTime),
this.expiryTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
canonicalName, key.getSignedObjectId() == null ? "" : key.getSignedObjectId(),
key.getSignedTenantId() == null ? "" : key.getSignedTenantId(),
key.getSignedStart() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedStart()),
key.getSignedExpiry() == null
? ""
: Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
key.getSignedService() == null ? "" : key.getSignedService(),
key.getSignedVersion() == null ? "" : key.getSignedVersion(),
this.authorizedAadObjectId == null ? "" : this.authorizedAadObjectId,
"", /* suoid - empty since this applies to HNS only accounts. */
this.correlationId == null ? "" : this.correlationId, "", /* new schema 2025-07-05 */
this.delegatedUserObjectId == null ? "" : this.delegatedUserObjectId,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(), VERSION, resource,
versionSegment == null ? "" : versionSegment, this.encryptionScope == null ? "" : this.encryptionScope,
this.cacheControl == null ? "" : this.cacheControl,
this.contentDisposition == null ? "" : this.contentDisposition,
this.contentEncoding == null ? "" : this.contentEncoding,
this.contentLanguage == null ? "" : this.contentLanguage,
this.contentType == null ? "" : this.contentType);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public final class BlobServiceSasSignatureValues {
private String preauthorizedAgentObjectId; /* saoid */
private String correlationId;
private String encryptionScope;
private String delegatedUserObjectId;

/**
* Creates an object with empty values for all fields.
Expand Down Expand Up @@ -575,6 +576,30 @@ public BlobServiceSasSignatureValues setCorrelationId(String correlationId) {
return this;
}

/**
* Optional. Beginning in version 2025-07-05, this value specifies the Entra ID of the user that is authorized to
* use the resulting SAS URL. The resulting SAS URL must be used in conjunction with an Entra ID token that has been
* issued to the user specified in this value.
*
* @return The Entra ID of the user that is authorized to use the resulting SAS URL.
*/
public String getDelegatedUserObjectId() {
return delegatedUserObjectId;
}

/**
* Optional. Beginning in version 2025-07-05, this value specifies the Entra ID of the user that is authorized to
* use the resulting SAS URL. The resulting SAS URL must be used in conjunction with an Entra ID token that has been
* issued to the user specified in this value.
*
* @param delegatedUserObjectId The Entra ID of the user that is authorized to use the resulting SAS URL.
* @return the updated BlobServiceSasSignatureValues object
*/
public BlobServiceSasSignatureValues setDelegatedUserObjectId(String delegatedUserObjectId) {
this.delegatedUserObjectId = delegatedUserObjectId;
return this;
}

/**
* Uses an account's shared key credential to sign these signature values to produce the proper SAS query
* parameters.
Expand Down Expand Up @@ -754,6 +779,7 @@ private String stringToSign(final UserDelegationKey key, String canonicalName) {
key.getSignedExpiry() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
key.getSignedService() == null ? "" : key.getSignedService(),
key.getSignedVersion() == null ? "" : key.getSignedVersion(),
this.delegatedUserObjectId == null ? "" : this.delegatedUserObjectId,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
VERSION_DEPRECATED_USER_DELEGATION_SAS_STRING_TO_SIGN, /* Pin down to version so old string to sign works. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -772,15 +772,19 @@ protected void liveTestScenarioWithRetry(Runnable runnable) {
}

int retry = 0;
while (retry < 5) {

// Try up to 5 times (4 retries + 1 final attempt)
while (retry < 4) {
try {
runnable.run();
break;
return; // success
} catch (Exception ex) {
retry++;
sleepIfRunningAgainstService(5000);
}
}
// Final attempt (5th try)
runnable.run();
}

protected HttpPipelinePolicy getPerCallVersionPolicy() {
Expand Down
Loading