0

As per this doc, I constructed SAS key.

Get the OAuth Token from Azure Ad. Generate user delegation key using OAuth. Generate SAS Token using user delegation key

However, I get the error

Access Denied. (message: 'Access to persistent storage path 'https://storage.blob.core.windows.net/container/dir/test.csv' was denied .

I do have rwdl permission. what am I doing wrong here ?

val xml = "" \\ User delegation xml
val signedOid     = (xml \ "SignedOid").text
val signedTid     = (xml \ "SignedTid").text
val signedKeyStart  = (xml \ "SignedStart").text
val signedKeyExpiry = (xml \ "SignedExpiry").text
val signedService = (xml \ "SignedService").text
val signedVersion = (xml \ "SignedVersion").text
val keyValue      = (xml \ "Value").text

   

// 2. Define SAS parameters
val resource = "c"  // 'c' for container-level access
val permissions = "rwdl"  
val sasStart = OffsetDateTime.now().minusMinutes(5).format(DateTimeFormatter.ISO_INSTANT)
val sasExpiry = OffsetDateTime.now().plusHours(1).format(DateTimeFormatter.ISO_INSTANT)
val protocol = "https"
val apiVersion = signedVersion

// 3. Construct the string to sign per Azure’s spec
val canonicalResource = s"/blob/storage/container"
val stringToSign = Seq(
  permissions,          // 1. signedPermissions
  sasStart,             // 2. signedStart
  sasExpiry,            // 3. signedExpiry
  canonicalResource,    // 4. canonicalizedResource
  signedOid,            // 5. signedObjectId
  signedTid,            // 6. signedTenantId
  signedKeyStart,       // 7. signedKeyStart
  signedKeyExpiry,      // 8. signedKeyExpiry
  signedService,        // 9. signedService
  signedVersion,        // 10. signedVersion
  "",                   // 11. signedAuthorizedUserObjectId
  "",                   // 12. signedUnauthorizedUserObjectId
  "",                   // 13. signedCorrelationId
  "",                   // 14. signedIP
  protocol,             // 15. signedProtocol (e.g., "https")
  "",                   // 16. signedEncryptionScope
  "",                   // 17. rscc - cache control
  "",                   // 18. rscd - content disposition
  "",                   // 19. rsce - content encoding
  "",                   // 20. rscl - content language
  "",                   // 21. rsct - content type
  resource              // 22. signedResource ("c" for container)
).mkString("\n")

    
// 4. Compute HMAC-SHA256 signature
val keyBytes = Base64.getDecoder.decode(keyValue)
val mac = Mac.getInstance("HmacSHA256")
mac.init(new SecretKeySpec(keyBytes, "HmacSHA256"))
val signatureBytes = mac.doFinal(stringToSign.getBytes("UTF-8"))
val signatureEncoded = URLEncoder.encode(Base64.getEncoder.encodeToString(signatureBytes), "UTF-8")

// 5. Build SAS token string
val sasToken = Seq(
  s"sp=$permissions",
  s"st=$sasStart",
  s"se=$sasExpiry",
  s"skoid=$signedOid",
  s"sktid=$signedTid",
  s"skt=$signedKeyStart",
  s"ske=$signedKeyExpiry",
  s"sks=$signedService",
  s"skv=$signedVersion",
  s"spr=$protocol",
  s"sv=$apiVersion",
  s"sr=$resource",
  s"sig=$signatureEncoded"
).mkString("&")

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.