question

JohnKennedy-4965 avatar image
0 Votes"
JohnKennedy-4965 asked JananiRamesh-MSFT answered

API Management Policy example to validate SHA256 signature from sorted and truncated query string parameters

We found an example of creating the signature from headers, but not the query string parameters. (https://docs.microsoft.com/en-us/azure/api-management/policies/generate-shared-access-signature) We are struggling to find relevant examples and documentation for the functionality we need in the policy to verify a SHA256 signature as we need to read the query string parameters, sort and truncate and hash the resulting string to compare to the sent signature.
This is for a Shopify webhook to verify it came from Shopify. They provide a Ruby example of it seen below. Any guidance on how to write this as an Azure API Management Policy would be much appreciated.

Thanks,
John



require 'openssl'
require 'rack/utils'
SHARED_SECRET = 'hush'

Use request.query_string in rails

query_string = "extra=1&extra=2&shop=shop-name.myshopify.com&path_prefix=%2Fapps%2Fawesome_reviews&timestamp=1317327555&signature=a9718877bea71c2484f91608a7eaea1532bdf71f5c56825065fa4ccabe549ef3"

query_hash = Rack::Utils.parse_query(query_string)

=> {

"extra" => ["1", "2"],

"shop" => "shop-name.myshopify.com",

"path_prefix" => "/apps/awesome_reviews",

"timestamp" => "1317327555",

"signature" => "a9718877bea71c2484f91608a7eaea1532bdf71f5c56825065fa4ccabe549ef3",

}


Remove and save the "signature" entry

signature = query_hash.delete("signature")

sorted_params = query_hash.collect{ |k, v| "#{k}=#{Array(v).join(',')}" }.sort.join

=> "extra=1,2path_prefix=/apps/awesome_reviewsshop=shop-name.myshopify.comtimestamp=1317327555"


calculated_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), SHARED_SECRET, sorted_params)
raise 'Invalid signature' unless ActiveSupport::SecurityUtils.secure_compare(signature, calculated_signature)

azure-api-management
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

JananiRamesh-MSFT avatar image
0 Votes"
JananiRamesh-MSFT answered

@JohnKennedy-4965 Thanks for reaching out. From the description I understand that you wanted to create a Shared access signature from the query string. In the document that you're referring they are generating the SAS key using the variables by passing the named values with the storage account details and not from the headers.

I see for creating a signature it requires open ssl, we don't support open ssl please refer this document to see the supported libraries.

Below is the policy to fetch the signature from the query string,

 <inbound>
         <set-variable name="signature" value="@{
      
 string querystring = context.Request.OriginalUrl.QueryString;
 string[] tokens = querystring.Split('&'); 
      
 return tokens[5];
 }" />
     </inbound>

I am not an expert in Ruby on rails, please provide the relevant code in c#, I will help you in writing a complete policy.
please let me know in case of further queries, I would be happy to assist you.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.