i trying to create SAS link to blob resource using PHP. Unfortunately currently in azure SDK there is no method for creating SAS signature.
I wrote a code for generating SAS but when i'm trying to get a resource by the link generated by this method i'm getting this message: Signature fields not well formed.
public function getSharedAccessSignatureURL($container, $blob)
{
$signedStart = date('c', strtotime('-1 day'));
$signedExpiry = date('c', strtotime('+1 day'));
$signedResource = 'b';
$signedPermission = 'r';
$signedIdentifier = '';
$responseContent = "file; attachment";
$responseType = "binary";
$canonicalizedResource = '/'.$this->account['accountName'].'/'.$container.'/'.$blob;
$signedVersion = '2014-02-14';
$stringToSign =
$signedPermission."\n".
$signedStart."\n".
$signedExpiry."\n".
$canonicalizedResource."\n".
$signedIdentifier."\n".
$signedVersion;
$signature = base64_encode(
hash_hmac(
'sha256',
urldecode(utf8_encode($stringToSign)),
$this->account['primaryKey'],
true
)
);
$arrayToUrl = [
'sv='.urlencode($signedVersion),
'st='.urlencode($signedStart),
'se='.urlencode($signedExpiry),
'sr='.urlencode($signedResource),
'sp='.urlencode($signedPermission),
'rscd='.urlencode($responseContent),
'rsct='.urlencode($responseType),
'sig='.urlencode($signature)
];
$url = 'https://'.$this->account['accountName'].'.blob.core.windows.net'.'/'
.$container.'/'
.$blob.'?'.implode('&', $arrayToUrl);
return $url;
}
Any suggest what i am doing wrong? I am commpletle newbie at Microsoft Azure
I believe there's an issue with your $stringToSign variable. Based on the documentation here: http://msdn.microsoft.com/en-US/library/azure/dn140255.aspx, your string to sign should be constructed like the following:
StringToSign = signedpermissions + "\n"
signedstart + "\n"
signedexpiry + "\n"
canonicalizedresource + "\n"
signedidentifier + "\n"
signedversion + "\n"
rscc + "\n"
rscd + "\n"
rsce + "\n"
rscl + "\n"
rsct
considering you're including rscd and rsct in your SAS querystring. Please try the following and see if that makes the difference:
$stringToSign =
$signedPermission."\n".
$signedStart."\n".
$signedExpiry."\n".
$canonicalizedResource."\n".
$signedIdentifier."\n".
$signedVersion."\n".
"\n".
$responseContent."\n".
"\n".
"\n".
$responseType;
UPDATE
Please try the code below. Replace the account name/key, container name and blob name with appropriate values:
<?php
$signedStart = gmdate('Y-m-d\TH:i:s\Z', strtotime('-1 day'));
echo $signedStart."\n";
$signedExpiry = gmdate('Y-m-d\TH:i:s\Z', strtotime('+1 day'));
echo $signedExpiry."\n";
$signedResource = 'b';
$signedPermission = 'r';
$signedIdentifier = '';
$accountName = "[account name]";
$accountKey = "[account key]";
$container = "[container name]";
$blob = "[blob name]";
$canonicalizedResource = '/'.$accountName.'/'.$container.'/'.$blob;
$signedVersion = '2014-02-14';
echo $canonicalizedResource."\n";
$rscc = '';
$rscd = 'file; attachment';//Content disposition
$rsce = '';
$rscl = '';
$rsct = 'binary';//Content type
$stringToSign =
$signedPermission."\n".
$signedStart."\n".
$signedExpiry."\n".
$canonicalizedResource."\n".
$signedIdentifier."\n".
$signedVersion."\n".
$rscc."\n".
$rscd."\n".
$rsce."\n".
$rscl."\n".
$rsct;
echo $stringToSign."\n";
$signature = base64_encode(
hash_hmac(
'sha256',
$stringToSign,
base64_decode($accountKey),
true
)
);
echo $signature."\n";
$arrayToUrl = [
'sv='.urlencode($signedVersion),
'st='.urlencode($signedStart),
'se='.urlencode($signedExpiry),
'sr='.urlencode($signedResource),
'sp='.urlencode($signedPermission),
'rscd='.urlencode($rscd),
'rsct='.urlencode($rsct),
'sig='.urlencode($signature)
];
$url = 'https://'.$accountName.'.blob.core.windows.net'.'/'
.$container.'/'
.$blob.'?'.implode('&', $arrayToUrl);
echo $url."\n";
?>
Essentially there were two issues (apart from incorrect $stringToSign variable):
Start/End date time were not properly formatted.
We would need to base64_decode the account key for calculating signature.
I run into exactly the same problem. But now you can use MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper which can handle a lot of problems for you. I has been added to the common libary 2 years ago in this PR (https://github.com/Azure/azure-storage-php/pull/73/files).
And it should be solved very simple like this:
$sasHelper = new SharedAccessSignatureHelper(
'nameofyouraccount',
'H...your-token...=='
);
$sas = $sasHelper->generateAccountSharedAccessSignatureToken(
'2018-11-09',
'rwl',
'b',
'sco',
(new \DateTime())->modify('+10 minute'),
(new \DateTime())->modify('-5 minute'),
'',
'https'
);
$connectionString = "BlobEndpoint=https://nameofyouraccount.blob.core.windows.net/;SharedAccessSignature={$sas}";
And you got your connection string!
modified and turned in to a function from #Gaurav Mantri
function generateSasToken($bucket,$key, $accountName, $accountKey){
$signedStart = gmdate('Y-m-d\TH:i:s\Z', time());
$signedExpiry = gmdate('Y-m-d\TH:i:s\Z', time()+3600);
$signedResource = 'b';
$signedPermission = 'r';
$signedIdentifier = '';
$canonicalizedResource = '/' . $accountName . '/' . $bucket . '/' . $key;
$signedVersion = '2014-02-14';
$rscc = '';
$rscd = 'file; attachment';//Content disposition
$rsce = '';
$rscl = '';
$rsct = 'binary';//Content type
$stringToSign =
$signedPermission . "\n" .
$signedStart . "\n" .
$signedExpiry . "\n" .
$canonicalizedResource . "\n" .
$signedIdentifier . "\n" .
$signedVersion . "\n" .
$rscc . "\n" .
$rscd . "\n" .
$rsce . "\n" .
$rscl . "\n" .
$rsct;
$signature = base64_encode(
hash_hmac(
'sha256',
$stringToSign,
base64_decode($accountKey),
true
)
);
$arrayToUrl = [
'sv=' . urlencode($signedVersion),
'st=' . urlencode($signedStart),
'se=' . urlencode($signedExpiry),
'sr=' . urlencode($signedResource),
'sp=' . urlencode($signedPermission),
'rscd=' . urlencode($rscd),
'rsct=' . urlencode($rsct),
'sig=' . urlencode($signature)
];
$url = 'https://' . $accountName . '.blob.core.windows.net' . '/'
. $bucket . '/'
. $key . '?' . implode('&', $arrayToUrl);
return $url;
}
Related
Getting response array blank when using health wellness api of garmin and not showing any error just give a blank array i'm confused not getting any solution for this my code is
public static function get_garmin_health_data(Request $request)
{
// dd(date('Y-m-d H:i:s'));
$garmin_consumer_key = env('CONSUMERKEY');
$garmin_consumer_secret = env('CONSUMERSECRET');
$twitter_access_token = $request->oauth_token ?? '';
$twitter_access_token_secret = $request->oauth_token_secret ?? '';
$twitter_version = '1.0';
$sign_method = 'HMAC-SHA1';
date_default_timezone_set('Asia/kolkata');
// $end_time = Carbon::now()->timestamp; // Produces something like 1552296328
// $start_time = Carbon::now()->subDays(1)->timestamp;
$start_time = strtotime('-20 hours');
$end_time = time();
// dd($start_time);
// $time = $request->oauth_nonce;
$time = time();
// $post = '{"event":{"type":"message_create","message_create":{"target":{"recipient_id":"123"},"message_data":{"text":"Hello world"}}}}';
$post = '{}';
$url = 'https://apis.garmin.com/wellness-api/rest/dailies';
$param_string = 'oauth_consumer_key=' . $garmin_consumer_key .
'&oauth_nonce=' . $time .
'&oauth_signature_method=' . $sign_method .
'&oauth_timestamp=' . $time .
'&oauth_token=' . $twitter_access_token .
'&oauth_version=' . $twitter_version .
'&uploadEndTimeInSeconds=' . $end_time .
'&uploadStartTimeInSeconds=' . $start_time;
//Generate a signature base string for POST
$base_string = 'GET&' . rawurlencode($url) . '&' . rawurlencode($param_string);
// dd($base_string);
$sign_key = rawurlencode($garmin_consumer_secret) . '&' . rawurlencode($twitter_access_token_secret);
//Generate a unique signature
$signature = base64_encode(hash_hmac('sha1', $base_string, $sign_key, true));
$curl_header = 'OAuth oauth_consumer_key="' . rawurlencode($garmin_consumer_key) . '", ' .
'oauth_nonce="' . rawurlencode($time) . '", ' .
'oauth_signature="' . rawurlencode($signature) . '", ' .
'oauth_signature_method="' . $sign_method . '", ' .
'oauth_timestamp="' . rawurlencode($time) . '", ' .
'oauth_token="' . rawurlencode($twitter_access_token) . '", ' .
'oauth_version="' . $twitter_version . '"';
$url2 = 'https://apis.garmin.com/wellness-api/rest/dailies?uploadStartTimeInSeconds=' . $start_time . '&uploadEndTimeInSeconds=' . $end_time;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url2,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Authorization:' . $curl_header,
),
));
$response = curl_exec($curl);
dd($response);
curl_close($curl);
$res = json_decode($response);
please suggest a solution for this question, if it is possible to answer in php or curl request.
I'm also working on this Garmin-health API and getting blank response(e.g:[]).
But i think so! i have zero activities in my profile that's why i'm getting this response.
i'm getting error
{"errorMessage":"[259fb762-b19e-448c-8989-f10368d4affc]Endpoint not enabled for summary type: WELLNESS_DAILY"}
while using garmin health wellness api my api code is:
public static function get_garmin_health_data(Request $request)
{
// dd(date('Y-m-d H:i:s'));
$garmin_consumer_key = env('CONSUMERKEY');
$garmin_consumer_secret = env('CONSUMERSECRETKEY');
$twitter_access_token = $request->oauth_token ?? '';
$twitter_access_token_secret = $request->oauth_token_secret ?? '';
$twitter_version = '1.0';
$sign_method = 'HMAC-SHA1';
date_default_timezone_set('Asia/kolkata');
// $end_time = Carbon::now()->timestamp; // Produces something like 1552296328
// $start_time = Carbon::now()->subDays(1)->timestamp;
$start_time = strtotime('-4 hours');
$end_time = time();
// dd($end_time);
// $time = $request->oauth_nonce;
$time = time();
// $post = '{"event":{"type":"message_create","message_create":{"target":{"recipient_id":"123"},"message_data":{"text":"Hello world"}}}}';
$post = '{}';
$url = 'https://healthapi.garmin.com/wellness-api/rest/backfill/dailies';
// $url = 'https://apis.garmin.com/wellness-api/rest/dailies';
$param_string = 'oauth_consumer_key=' . $garmin_consumer_key .
'&oauth_nonce=' . $time .
'&oauth_signature_method=' . $sign_method .
'&oauth_timestamp=' . $time .
'&oauth_token=' . $twitter_access_token .
'&oauth_version=' . $twitter_version .
'&summaryEndTimeInSeconds=' . $end_time .
'&summaryStartTimeInSeconds=' . $start_time;
//Generate a signature base string for POST
$base_string = 'GET&' . rawurlencode($url) . '&' . rawurlencode($param_string);
$sign_key = rawurlencode($garmin_consumer_secret) . '&' . rawurlencode($twitter_access_token_secret);
//Generate a unique signature
$signature = base64_encode(hash_hmac('sha1', $base_string, $sign_key, true));
$curl_header = 'OAuth oauth_consumer_key="' . rawurlencode($garmin_consumer_key) . '", ' .
'oauth_nonce="' . rawurlencode($time) . '", ' .
'oauth_signature="' . rawurlencode($signature) . '", ' .
'oauth_signature_method="' . $sign_method . '", ' .
'oauth_timestamp="' . rawurlencode($time) . '", ' .
'oauth_token="' . rawurlencode($twitter_access_token) . '", ' .
'oauth_version="' . $twitter_version . '"';
$url2 = 'https://healthapi.garmin.com/wellness-api/rest/backfill/dailies?summaryStartTimeInSeconds=' . $start_time . '&summaryEndTimeInSeconds=' . $end_time;
// $url2 = 'https://apis.garmin.com/wellness-api/rest/dailies?uploadStartTimeInSeconds=' . $start_time . '&uploadEndTimeInSeconds=' . $end_time;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url2,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Authorization:' . $curl_header,
),
));
$response = curl_exec($curl);
dd($response);
curl_close($curl);
$res = json_decode($response);
please suggest me the answers for this if it is possible post solution in php or curl request
When I am trying to integrate the PayU integration. Whatever changes I do I am getting invalid hash. I think I am doing something minor mistake.
For generating the hash I have written in PHP though currently, all data is static I have matched all are same only.
In the following php example I am using payment_related_details_for_mobile_sdk_hash key in android
Here is my code:
paymentIntegration("741852963", "1.0", "SmartAuto", "Piyush", "piyush.sahay#mail.com", "330122983a2492fe6ff18ad2fcccc6a78ed499f988a6b06b226ff4f27b9b390356f18c297282105b2dbb70166bfd0c2332dfa4e55a784543658bd67330f98b39", "XXXXX:XXXXX#XXXXX.com");
private void paymentIntegration(String txnId, String amount, String productName, String userName, String userEmail, String hash1, String userCredentials) {
HashMap<String, Object> additionalParams = new HashMap<>();
additionalParams.put(PayUCheckoutProConstants.CP_UDF1, "udf1");
additionalParams.put(PayUCheckoutProConstants.CP_UDF2, "udf2");
additionalParams.put(PayUCheckoutProConstants.CP_UDF3, "udf3");
additionalParams.put(PayUCheckoutProConstants.CP_UDF4, "udf4");
additionalParams.put(PayUCheckoutProConstants.CP_UDF5, "udf5");
PayUPaymentParams.Builder builder = new PayUPaymentParams.Builder();
builder.setAmount(amount)
.setIsProduction(true)
.setProductInfo(productName)
.setKey(MERCHANT_KEY)
.setPhone("XXXXXXXX")
.setTransactionId(txnId)
.setFirstName(userName)
.setEmail(userEmail)
.setSurl("https://payu.herokuapp.com/success")
.setFurl("https://payu.herokuapp.com/failure")
.setUserCredential(userCredentials)
.setAdditionalParams(additionalParams);
PayUPaymentParams payUPaymentParams = builder.build();
PayUCheckoutPro.open(
this,
payUPaymentParams,
new PayUCheckoutProListener() {
#Override
public void onPaymentSuccess(Object response) {
//Cast response object to HashMap
HashMap<String,Object> result = (HashMap<String, Object>) response;
String payuResponse = (String)result.get(PayUCheckoutProConstants.CP_PAYU_RESPONSE);
String merchantResponse = (String) result.get(PayUCheckoutProConstants.CP_MERCHANT_RESPONSE);
}
#Override
public void onPaymentFailure(Object response) {
//Cast response object to HashMap
HashMap<String,Object> result = (HashMap<String, Object>) response;
String payuResponse = (String)result.get(PayUCheckoutProConstants.CP_PAYU_RESPONSE);
String merchantResponse = (String) result.get(PayUCheckoutProConstants.CP_MERCHANT_RESPONSE);
}
#Override
public void onPaymentCancel(boolean isTxnInitiated) {
}
#Override
public void onError(ErrorResponse errorResponse) {
String errorMessage = errorResponse.getErrorMessage();
Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
}
#Override
public void setWebViewProperties(#Nullable WebView webView, #Nullable Object o) {
//For setting webview properties, if any. Check Customized Integration section for more details on this
}
#Override
public void generateHash(HashMap<String, String> valueMap, PayUHashGenerationListener hashGenerationListener) {
String hashName = valueMap.get(PayUCheckoutProConstants.CP_HASH_NAME);
String hashData = valueMap.get(PayUCheckoutProConstants.CP_HASH_STRING);
if (!TextUtils.isEmpty(hashName) && !TextUtils.isEmpty(hashData)) {
//Do not generate hash from local, it needs to be calculated from server side only. Here, hashString contains hash created from your server side.
String hash = hash1;
HashMap<String, String> dataMap = new HashMap<>();
dataMap.put(hashName, hash);
hashGenerationListener.onHashGenerated(dataMap);
}
}
}
);
}
Here is my PHP Code for a hash generation:
$output=getHashes("741852963", "1.0", "SmartAuto", "Piyush", "piyush.sahay#gmail.com", "XXXXX:XXXXX#XXXXX.com","udf1","udf2","udf3","udf4","udf5","","" );
function getHashes($txnid, $amount, $productinfo, $firstname, $email, $user_credentials, $udf1, $udf2, $udf3, $udf4, $udf5,$offerKey,$cardBin)
{
// $firstname, $email can be "", i.e empty string if needed. Same should be sent to PayU server (in request params) also.
$key = 'XXXXX';
$salt = 'XXXXXX';
$payhash_str = $key . '|' . checkNull($txnid) . '|' .checkNull($amount) . '|' .checkNull($productinfo) . '|' . checkNull($firstname) . '|' . checkNull($email) . '|' . checkNull($udf1) . '|' . checkNull($udf2) . '|' . checkNull($udf3) . '|' . checkNull($udf4) . '|' . checkNull($udf5) . '||||||' . $salt;
$paymentHash = strtolower(hash('sha512', $payhash_str));
$arr['payment_hash'] = $paymentHash;
$cmnNameMerchantCodes = 'get_merchant_ibibo_codes';
$merchantCodesHash_str = $key . '|' . $cmnNameMerchantCodes . '|default|' . $salt ;
$merchantCodesHash = strtolower(hash('sha512', $merchantCodesHash_str));
$arr['get_merchant_ibibo_codes_hash'] = $merchantCodesHash;
$cmnMobileSdk = 'vas_for_mobile_sdk';
$mobileSdk_str = $key . '|' . $cmnMobileSdk . '|default|' . $salt;
$mobileSdk = strtolower(hash('sha512', $mobileSdk_str));
$arr['vas_for_mobile_sdk_hash'] = $mobileSdk;
$cmnPaymentRelatedDetailsForMobileSdk1 = 'payment_related_details_for_mobile_sdk';
$detailsForMobileSdk_str1 = $key . '|' . $cmnPaymentRelatedDetailsForMobileSdk1 . '|default|' . $salt ;
$detailsForMobileSdk1 = strtolower(hash('sha512', $detailsForMobileSdk_str1));
$arr['payment_related_details_for_mobile_sdk_hash'] = $detailsForMobileSdk1;
//used for verifying payment(optional)
$cmnVerifyPayment = 'verify_payment';
$verifyPayment_str = $key . '|' . $cmnVerifyPayment . '|'.$txnid .'|' . $salt;
$verifyPayment = strtolower(hash('sha512', $verifyPayment_str));
$arr['verify_payment_hash'] = $verifyPayment;
if($user_credentials != NULL && $user_credentials != '')
{
$cmnNameDeleteCard = 'delete_user_card';
$deleteHash_str = $key . '|' . $cmnNameDeleteCard . '|' . $user_credentials . '|' . $salt ;
$deleteHash = strtolower(hash('sha512', $deleteHash_str));
$arr['delete_user_card_hash'] = $deleteHash;
$cmnNameGetUserCard = 'get_user_cards';
$getUserCardHash_str = $key . '|' . $cmnNameGetUserCard . '|' . $user_credentials . '|' . $salt ;
$getUserCardHash = strtolower(hash('sha512', $getUserCardHash_str));
$arr['get_user_cards_hash'] = $getUserCardHash;
$cmnNameEditUserCard = 'edit_user_card';
$editUserCardHash_str = $key . '|' . $cmnNameEditUserCard . '|' . $user_credentials . '|' . $salt ;
$editUserCardHash = strtolower(hash('sha512', $editUserCardHash_str));
$arr['edit_user_card_hash'] = $editUserCardHash;
$cmnNameSaveUserCard = 'save_user_card';
$saveUserCardHash_str = $key . '|' . $cmnNameSaveUserCard . '|' . $user_credentials . '|' . $salt ;
$saveUserCardHash = strtolower(hash('sha512', $saveUserCardHash_str));
$arr['save_user_card_hash'] = $saveUserCardHash;
$cmnPaymentRelatedDetailsForMobileSdk = 'payment_related_details_for_mobile_sdk';
$detailsForMobileSdk_str = $key . '|' . $cmnPaymentRelatedDetailsForMobileSdk . '|' . $user_credentials . '|' . $salt ;
$detailsForMobileSdk = strtolower(hash('sha512', $detailsForMobileSdk_str));
$arr['payment_related_details_for_mobile_sdk_hash'] = $detailsForMobileSdk;
}
// if($udf3!=NULL && !empty($udf3)){
$cmnSend_Sms='send_sms';
$sendsms_str=$key . '|' . $cmnSend_Sms . '|' . $udf3 . '|' . $salt;
$send_sms = strtolower(hash('sha512',$sendsms_str));
$arr['send_sms_hash']=$send_sms;
// }
if ($offerKey!=NULL && !empty($offerKey)) {
$cmnCheckOfferStatus = 'check_offer_status';
$checkOfferStatus_str = $key . '|' . $cmnCheckOfferStatus . '|' . $offerKey . '|' . $salt ;
$checkOfferStatus = strtolower(hash('sha512', $checkOfferStatus_str));
$arr['check_offer_status_hash']=$checkOfferStatus;
}
if ($cardBin!=NULL && !empty($cardBin)) {
$cmnCheckIsDomestic = 'check_isDomestic';
$checkIsDomestic_str = $key . '|' . $cmnCheckIsDomestic . '|' . $cardBin . '|' . $salt ;
$checkIsDomestic = strtolower(hash('sha512', $checkIsDomestic_str));
$arr['check_isDomestic_hash']=$checkIsDomestic;
}
return $arr;
}
function checkNull($value) {
if ($value == null) {
return '';
} else {
return $value;
}
}
echo json_encode($output);
I am working on aws signature version 4. Now my concern is that I receive signature from api request at Amazon api gateway and gateway auhorize and authenticate the request and forward to php microservice. Now I want to detect user from signature that is in request headers. How I can resolve this issue.
Below is my working code through I generate aws signature
public function generateAWSToken($uid) {
try {
$method = 'GET';
$uri = '/dev';
$json = file_get_contents('php://input');
$obj = json_decode($json);
if (isset($obj->method)) {
$m = explode("|", $obj->method);
$method = $m[0];
$uri .= $m[1];
}
$secretKey = env('AWS_SECRET_ACCESS_KEY');
$access_key = env('AKIAJR2JSY655JXI5LIA');
$token = env('AWS_SECRET_ACCESS_KEY');
$region = env('AWS_DEFAULT_REGIO');
$service = 'execute-api';
$options = array();
$headers = array();
$host = "YOUR-API-HOST.execute-api.ap-southeast-1.amazonaws.com";
//Or you can define your host here.. I am using API gateway.
$alg = 'sha256';
$date = new \DateTime('UTC');
$dd = $date->format('Ymd\THis\Z');
$amzdate2 = new \DateTime('UTC');
$amzdate2 = $amzdate2->format('Ymd');
$amzdate = $dd;
$algorithm = 'AWS4-HMAC-SHA256';
// $parameters = (array) $obj->data;
if (isset($obj->data) && ($obj->data == null || empty($obj->data))) {
$obj->data = "";
} else {
$param = "";
// $param = json_encode($obj->data);
// if ($param == "{}") {
// $param = "";
// }
$requestPayload = strtolower($param);
$hashedPayload = hash($alg, $uid);
$canonical_uri = $uri;
$canonical_querystring = '';
$canonical_headers = "content-type:" . "application/json" . "\n" . "host:" . $host . "\n" . "x-amz-date:" . $amzdate . "\n" . "x-amz-security-token:" . $token . "\n";
$signed_headers = 'content-type;host;x-amz-date;x-amz-security-token';
$canonical_request = "" . $method . "\n" . $canonical_uri . "\n" . $canonical_querystring . "\n" . $canonical_headers . "\n" . $signed_headers . "\n" . $hashedPayload;
$credential_scope = $amzdate2 . '/' . $region . '/' . $service . '/' . 'aws4_request';
$string_to_sign = "" . $algorithm . "\n" . $amzdate . "\n" . $credential_scope . "\n" . hash('sha256', $canonical_request) . "";
//string_to_sign is the answer..hash('sha256', $canonical_request)//
$kSecret = 'AWS4' . $secretKey;
$kDate = hash_hmac($alg, $amzdate2, $kSecret, true);
$kRegion = hash_hmac($alg, $region, $kDate, true);
$kService = hash_hmac($alg, $service, $kRegion, true);
$kSigning = hash_hmac($alg, 'aws4_request', $kService, true);
$signature = hash_hmac($alg, $string_to_sign, $kSigning);
$authorization_header = $algorithm . ' ' . 'Credential=' . $access_key . '/' . $credential_scope . ', ' . 'SignedHeaders=' . $signed_headers . ', ' . 'Signature=' . $signature;
$headers = [
'content-type' => 'application/json',
'x-amz-security-token' => $token,
'x-amz-date' => $amzdate,
'Authorization' => $authorization_header];
return $signature;
}
} catch (\Exception $ex) {
return false;
}
}
Suggest any usefull link and method.
How are you generating the AKS+AKI+token? If you are using Cognito pools & identity federation, this should be helpful. This helped me
how to user identity id to link to cognito user pool
PS: this might be a copy-paste error but surely the token is not $token = env('AWS_SECRET_ACCESS_KEY');
This is the error returned when I try to access a blob in storage:
Code: AuthenticationFailed
Message: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
AuthenticationErrorDetail: Signature did not match. String to sign used was xxstorageaccount rwdlac b sco 2017-08-17T21:29:24Z 2017-08-17T21:34:24Z https 2017-04-17
Here's my code:
$storageAccount = config('azure.storage.account');
$start = new \DateTime();
$end = (new \DateTime())->modify('+5 minutes');
$start = $start->format('Y-m-d\TH:i:s\Z');
$end = $end->format('Y-m-d\TH:i:s\Z');
$toSign = $storageAccount . "\n";
$toSign .= "rwdlac" . "\n";
$toSign .= "b" . "\n";
$toSign .= "sco" . "\n";
$toSign .= $start . "\n";
$toSign .= $end . "\n";
$toSign .= "\n";
$toSign .= "https" . "\n";
$toSign .= "2017-04-17" . "\n";
$signature = rawurlencode(base64_encode(hash_hmac('sha256', $toSign, $sasKeyValue, TRUE)));
$token = "?sv=2017-04-17&ss=b&srt=sco&sp=rwdlac&se=" . $end . "&st=" . $start . "&spr=https&sig=" . $signature;
return $uri . $token;
You could do 2 things to avoid this error.
Convert start and end time to GMT time via setTimezone() function or consider using the gmdate function instead.
Decode base64 account key through base64_decode() function.
Please change your code like the following:
$storageAccount = config('azure.storage.account');
$start = (new \DateTime())->setTimezone(new DateTimeZone('GMT'));
$end = (new \DateTime())->setTimezone(new DateTimeZone('GMT'))->modify('+5 minutes');
$start = $start->format('Y-m-d\TH:i:s\Z');
$end = $end->format('Y-m-d\TH:i:s\Z');
$toSign = $storageAccount . "\n";
$toSign .= "rwdlac" . "\n";
$toSign .= "b" . "\n";
$toSign .= "sco" . "\n";
$toSign .= $start . "\n";
$toSign .= $end . "\n";
$toSign .= "\n";
$toSign .= "https" . "\n";
$toSign .= "2017-04-17" . "\n";
$signature = rawurlencode(base64_encode(hash_hmac('sha256', $toSign, base64_decode($sasKeyValue), TRUE)));
$token = "?sv=2017-04-17&ss=b&srt=sco&sp=rwdlac&se=" . $end . "&st=" . $start . "&spr=https&sig=" . $signature;
return $uri . $token;