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×tamp=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)