Skip to content

Commit 9312447

Browse files
author
sfomuseumbot
committed
prove that lib_aws_signer_v4.php works, update docs
1 parent 9438864 commit 9312447

File tree

2 files changed

+119
-15
lines changed

2 files changed

+119
-15
lines changed

README.md

+60-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,66 @@
11
# flamework-aws
22

3-
## Important
3+
Limited (and opionated) methods for working with AWS services in a Flamework-based application.
44

5-
This is work in progress. It is not complete and it will change.
5+
## Documentation
6+
7+
### lib_aws_signer_v4.php
8+
9+
#### aws_signer_v4_headers($http_method, $uri, $region, $service, $creds, $data, $debug=FALSE)
10+
11+
Return an array containing the necessary header for executing an AWS "v4" signed request. For example:
12+
13+
```
14+
$http_method = "POST";
15+
$uri = "https://{SOME_FUNCTION_URL}.lambda-url.{REGION}.on.aws/api/point-in-polygon";
16+
$region = "{REGION}";
17+
$service = "lambda";
18+
19+
// How and where these AWS credentials are derived is left to be determined on a per-application basis.
20+
$creds = array(
21+
"access_key" => "...",
22+
"secret_key" => "...",
23+
"security_token" => "...",
24+
);
25+
26+
$data = json_encode(array("latitude" => 25.0, "longitude" => -45.6 ));
27+
28+
$headers = aws_signer_v4_headers($http_method, $uri, $region, $service, $creds, $data);
29+
dumper($headers);
30+
```
31+
32+
#### aws_signer_v4_execute_request($http_method, $uri, $region, $service, $creds, $data)
33+
34+
Execute an AWS "v4" signed request and return the result. For example:
35+
36+
```
37+
$http_method = "POST";
38+
$uri = "https://{SOME_FUNCTION_URL}.lambda-url.{REGION}.on.aws/api/point-in-polygon";
39+
$region = "{REGION}";
40+
$service = "lambda";
41+
42+
// How and where these AWS credentials are derived is left to be determined on a per-application basis.
43+
$creds = array(
44+
"access_key" => "...",
45+
"secret_key" => "...",
46+
"security_token" => "...",
47+
);
48+
49+
$data = json_encode(array("latitude" => 25.0, "longitude" => -45.6 ));
50+
51+
$rsp = aws_signer_v4_execute_request($http_method, $uri, $region, $service, $creds, $data);
52+
dumper($rsp);
53+
```
54+
55+
Which, in this example, would return something like:
56+
57+
```
58+
array (
59+
'ok' => 1,
60+
'body' => '{"places":[{"wof:id":"404528709","wof:parent_id":"-1","wof:name":"North Atlantic Ocean","wof:country":"","wof:placetype":"ocean","mz:latitude":0,"mz:longitude":0,"mz:min_latitude":24.965357,"mz:min_longitude":0,"mz:max_latitude":-45.616087,"mz:max_longitude":-45.570425,"mz:is_current":1,"mz:is_deprecated":-1,"mz:is_ceased":-1,"mz:is_superseded":0,"mz:is_superseding":0,"edtf:inception":"","edtf:cessation":"","wof:supersedes":[],"wof:superseded_by":[],"wof:belongsto":[],"wof:path":"404/528/709/404528709.geojson","wof:repo":"whosonfirst-data-admin-xy","wof:lastmodified":1690923898}]}
61+
',
62+
)
63+
```
664

765
## See also
866

www/include/lib_aws_signer_v4.php

+59-13
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,59 @@
11
<?php
22

3-
# WORK IN PROGRESS. EVERYTHING WILL CHANGE.
4-
# Derived from https://github.com/avi-wish/aws4-signature-php
3+
# This was originally derived from https://github.com/avi-wish/aws4-signature-php
54

65
# If you need to verify / sanity check things against a known-working implementation:
76
# https://github.com/aaronland/go-aws-auth?tab=readme-ov-file#aws-sign-request
87

9-
function aws_signer_v4_execute_request($http_method, $uri, $region, $service, $access_key, $secret_key, $security_token="", $data){
8+
function aws_signer_v4_execute_request($http_method, $uri, $region, $service, $creds, $data){
109

11-
$headers = aws_signer_v4_headers($http_method, $uri, $region, $service, $access_key, $secret_key, $security_token);
10+
$headers = aws_signer_v4_headers($http_method, $uri, $region, $service, $creds, $data);
1211

13-
switch (strtouppper($http_method)){
12+
// START OF for reasons I do not understand
13+
// there is something about using the lib_http methods (below) that makes AWS sad
14+
// and return "403 Forbidden" errors. For the sake of expediency we are just going
15+
// to call the native curl functions until I can figure out what is going on.
16+
17+
$ch = curl_init();
18+
19+
curl_setopt_array($ch, array(
20+
CURLOPT_URL => $uri,
21+
CURLOPT_RETURNTRANSFER => true,
22+
CURLOPT_FOLLOWLOCATION => true,
23+
CURLOPT_TIMEOUT => 30,
24+
CURLOPT_POST => true,
25+
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
26+
CURLOPT_CUSTOMREQUEST => $http_method,
27+
CURLOPT_POSTFIELDS => $data,
28+
CURLOPT_VERBOSE => 0,
29+
CURLOPT_SSL_VERIFYHOST => 1,
30+
CURLOPT_SSL_VERIFYPEER => 1,
31+
CURLOPT_HEADER => false,
32+
CURLINFO_HEADER_OUT=>true,
33+
CURLOPT_HTTPHEADER => $headers,
34+
));
35+
36+
$rsp = curl_exec($ch);
37+
$rsp_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
38+
39+
curl_close($ch);
40+
41+
if (($rsp_code >= 200) && ($rsp_code <= 299)){
42+
return array("ok" => 1, "body" => $rsp);
43+
}
44+
45+
$err = curl_error($ch);
46+
47+
if ($err != ""){
48+
$rsp = $err;
49+
}
50+
51+
return array("ok" => 0, "error" => $rsp);
52+
53+
// END OF for reasons I do not understand
54+
55+
/*
56+
switch (strtoupper($http_method)){
1457
case "GET":
1558
return http_get($uri, $headers);
1659
break;
@@ -27,15 +70,18 @@ function aws_signer_v4_execute_request($http_method, $uri, $region, $service, $a
2770
return array("ok" => 0, "error" => "Unsupported method");
2871
break;
2972
}
73+
*/
3074
}
3175

32-
// function aws_signer_v4_headers($host, $uri, $requestUrl, $accessKey, $secretKey, $securityToken, $region, $service, $httpRequestMethod, $data, $debug = FALSE){
33-
34-
function aws_signer_v4_headers($http_method, $uri, $region, $service, $access_key, $secret_key, $security_token, $debug=FALSE){
76+
function aws_signer_v4_headers($http_method, $uri, $region, $service, $creds, $data, $debug=FALSE){
3577

3678
$host = parse_url($uri, PHP_URL_HOST);
3779
$path = parse_url($uri, PHP_URL_PATH);
3880
$query = parse_url($uri, PHP_URL_QUERY);
81+
82+
$access_key = $creds["access_key"];
83+
$secret_key = $creds["secret_key"];
84+
$security_token = $creds["security_token"];
3985

4086
$headers_to_sign = array(
4187
"content-length",
@@ -58,7 +104,7 @@ function aws_signer_v4_headers($http_method, $uri, $region, $service, $access_ke
58104
$dt = new DateTime('UTC');
59105
$req_date = $dt->format('Ymd');
60106
$req_datetime = $dt->format('Ymd\THis\Z');
61-
107+
62108
// Create signing key
63109
$k_secret = $secret_key;
64110
$k_date = hash_hmac($php_algorithm, $req_date, "AWS4{$k_secret}", true);
@@ -100,20 +146,20 @@ function aws_signer_v4_headers($http_method, $uri, $region, $service, $access_ke
100146
}
101147

102148
$canonical_request_hashed = strtolower(bin2hex(hash($php_algorithm, $canonical_request_str, true)));
103-
149+
104150
// Create scope
105151
$credential_scope = array();
106152
$credential_scope[] = $req_date;
107153
$credential_scope[] = $region;
108154
$credential_scope[] = $service;
109155
$credential_scope[] = $termination_string;
110-
$credential_scopeStr = implode('/', $credential_scope);
156+
$credential_scope_str = implode('/', $credential_scope);
111157

112158
// Create string to signing
113159
$to_sign = array();
114160
$to_sign[] = $algorithm;
115161
$to_sign[] = $req_datetime;
116-
$to_sign[] = $credential_scopeStr;
162+
$to_sign[] = $credential_scope_str;
117163
$to_sign[] = $canonical_request_hashed;
118164
$to_sign_str = implode("\n", $to_sign);
119165

@@ -130,7 +176,7 @@ function aws_signer_v4_headers($http_method, $uri, $region, $service, $access_ke
130176

131177
// Create authorization header
132178
$auth_header = array();
133-
$auth_header[] = 'Credential=' . $access_key . '/' . $credential_scopeStr;
179+
$auth_header[] = 'Credential=' . $access_key . '/' . $credential_scope_str;
134180
$auth_header[] = 'SignedHeaders=' . $signed_headers;
135181
$auth_header[] = 'Signature=' . ($signature);
136182
$auth_header_str = $algorithm . ' ' . implode(', ', $auth_header);

0 commit comments

Comments
 (0)