|
1 |
| -# aws-api-sig-v4-filemaker |
| 1 | +# aws-api-sig-v4-filemaker |
| 2 | + |
| 3 | +## Blog |
| 4 | + |
| 5 | +### Japanese |
| 6 | + |
| 7 | +- [FileMaker から S3 や EC2 などの AWS の API を利用する方法](https://frudens.jp/how-to-use-aws-apis-s3-ec2-from-filemaker) |
| 8 | + |
| 9 | +### English |
| 10 | + |
| 11 | +- I am writing. |
| 12 | + |
| 13 | +## Account |
| 14 | + |
| 15 | +``` |
| 16 | +AccountName = Administrator |
| 17 | +Password = administrator |
| 18 | +``` |
| 19 | + |
| 20 | +## File |
| 21 | + |
| 22 | +### frudens_amazon_signature_v4_learning_material.fmp12 |
| 23 | + |
| 24 | +- This is a sample file for learning. |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +### frudens_amazon_your_custom_app.fmp12 |
| 29 | + |
| 30 | +- A file for custom functions to include in your custom app. |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | +## CustomFunction |
| 35 | + |
| 36 | +### aws_v4_sign_envJson |
| 37 | + |
| 38 | +``` |
| 39 | +aws_v4_sign_envJson ( _accessKeyId ; _secretAccessKey ; _region ; _service ; _method ; _host ; _canonicalURI ; _canonicalQueryString ; _hashedPayload ; _optionJsonObject ) |
| 40 | +
|
| 41 | +-------------------------------------------------- |
| 42 | +
|
| 43 | +Let ( [ |
| 44 | +
|
| 45 | + ~timestamp = GetAsTimestamp ( Int ( Get ( CurrentTimeUTCMilliseconds ) / 1000 ) ) ; |
| 46 | + ~date = GetAsDate ( ~timestamp ) ; |
| 47 | + ~dateY = Year ( ~date ) ; |
| 48 | + ~dateM = Right ( "0" & Month ( ~date ) ; 2 ) ; |
| 49 | + ~dateD = Right ( "0" & Day ( ~date ) ; 2 ) ; |
| 50 | +
|
| 51 | + ~time = GetAsTime ( ~timestamp ) ; |
| 52 | + ~timeH = Right ( "0" & Hour ( ~time ) ; 2 ) ; |
| 53 | + ~timeM = Right ( "0" & Minute ( ~time ) ; 2 ) ; |
| 54 | + ~timeS = Right ( "0" & Seconds ( ~time ) ; 2 ) ; |
| 55 | +
|
| 56 | + ~timestampFormat = ~dateY & ~dateM & ~dateD & "T" & ~timeH & ~timeM & ~timeS & "Z" ; |
| 57 | + ~dateFormat = ~dateY & ~dateM & ~dateD ; |
| 58 | +
|
| 59 | + ~envJson = |
| 60 | + JSONSetElement ( _optionJsonObject ; |
| 61 | + [ "accessKeyId" ; _accessKeyId ; JSONString ] ; |
| 62 | + [ "secretAccessKey" ; _secretAccessKey ; JSONString ] ; |
| 63 | +
|
| 64 | + [ "region" ; _region ; JSONString ] ; |
| 65 | + [ "service" ; _service ; JSONString ] ; |
| 66 | +
|
| 67 | + [ "method" ; Upper ( _method ) ; JSONString ] ; |
| 68 | + [ "host" ; _host ; JSONString ] ; |
| 69 | + [ "canonicalURI" ; _canonicalURI ; JSONString ] ; |
| 70 | + [ "canonicalQueryString" ; _canonicalQueryString ; JSONString ] ; |
| 71 | + [ "hashedPayload" ; _hashedPayload ; JSONString ] ; |
| 72 | +
|
| 73 | + [ "timestamp" ; ~timestampFormat ; JSONString ] ; |
| 74 | + [ "date" ; ~dateFormat ; JSONString ] |
| 75 | + ) |
| 76 | +
|
| 77 | +] ; |
| 78 | +
|
| 79 | +~envJson |
| 80 | +
|
| 81 | +) /*let*/ |
| 82 | +``` |
| 83 | + |
| 84 | +### aws_v4_sign_generate_authorization ( _envJson ) |
| 85 | + |
| 86 | +``` |
| 87 | +aws_v4_sign_generate_authorization ( _envJson ) |
| 88 | +
|
| 89 | +-------------------------------------------------- |
| 90 | +
|
| 91 | +Let ( [ |
| 92 | +
|
| 93 | + // env |
| 94 | + ~isJson = not Exact ( Left ( JSONFormatElements ( _envJson ) ; 1 ) ; "?" ) ; |
| 95 | + ~env = If ( ~isJson ; _envJson ; "{}" ) ; |
| 96 | + ~timestamp = JSONGetElement ( ~env ; "timestamp" ) ; |
| 97 | + ~date = JSONGetElement ( ~env ; "date" ) ; |
| 98 | + ~region = JSONGetElement ( ~env ; "region" ) ; |
| 99 | + ~service = JSONGetElement ( ~env ; "service" ) ; |
| 100 | +
|
| 101 | + // CanonicalRequest |
| 102 | + ~method = Upper ( JSONGetElement ( ~env ; "method" ) ) ; |
| 103 | + ~canonicalURI = JSONGetElement ( ~env ; "canonicalURI" ) ; |
| 104 | + ~canonicalQueryString = JSONGetElement ( ~env ; "canonicalQueryString" ) ; |
| 105 | +
|
| 106 | + ~header1 = "host:" & JSONGetElement ( ~env ; "host" ) ; |
| 107 | + ~header2 = "x-amz-content-sha256:" & JSONGetElement ( ~env ; "hashedPayload" ) ; |
| 108 | + ~header3 = "x-amz-date:" & ~timestamp ; |
| 109 | + ~canonicalHeaders = List ( ~header1 ; ~header2 ; ~header3 ) ; |
| 110 | +
|
| 111 | + ~signedHeaders = "host;x-amz-content-sha256;x-amz-date" ; |
| 112 | + ~hashedPayload = JSONGetElement ( ~env ; "hashedPayload" ) ; |
| 113 | +
|
| 114 | + ~canonicalRequest = ~method & "¶" & ~canonicalURI & "¶" & ~canonicalQueryString & "¶" & ~canonicalHeaders & "¶" & "¶" & ~signedHeaders & "¶" & ~hashedPayload ; |
| 115 | +
|
| 116 | + // HashCanonicalRequest |
| 117 | + ~hashCanonicalRequest = Lower ( HexEncode ( CryptDigest ( TextEncode ( ~canonicalRequest ; "utf-8" ; 3 ) ; "SHA256" ) ) ) ; |
| 118 | +
|
| 119 | + // CredentialScope |
| 120 | + ~credentialScope = ~date & "/" & ~region & "/" & ~service & "/aws4_request" ; |
| 121 | +
|
| 122 | + // StringToSign |
| 123 | + ~stringToSign = List ( "AWS4-HMAC-SHA256" ; ~timestamp ; ~credentialScope ; ~hashCanonicalRequest ) ; |
| 124 | +
|
| 125 | + // Signature |
| 126 | + ~kSecret = JSONGetElement ( ~env ; "secretAccessKey" ) ; |
| 127 | + ~kDate = CryptAuthCode ( ~date ; "SHA256" ; "AWS4" & ~kSecret ) ; |
| 128 | + ~kRegion = CryptAuthCode ( ~region ; "SHA256" ; ~kDate ) ; |
| 129 | + ~kService = CryptAuthCode ( ~service ; "SHA256" ; ~kRegion ) ; |
| 130 | + ~kSigning = CryptAuthCode ( "aws4_request" ; "SHA256" ; ~kService ) ; |
| 131 | + ~signature = Lower ( HexEncode ( CryptAuthCode ( TextEncode ( ~stringToSign ; "utf-8" ; 3 ) ; "SHA256" ; ~kSigning ) ) ) ; |
| 132 | +
|
| 133 | + // Authorization |
| 134 | + ~authorizationTemplate = "{algorithm} Credential={accessKeyId}/{credentialScope}, SignedHeaders={signedHeaders}, Signature={signature}" ; |
| 135 | + ~authorization = |
| 136 | + Substitute ( |
| 137 | + ~authorizationTemplate ; |
| 138 | + [ "{algorithm}" ; "AWS4-HMAC-SHA256" ] ; |
| 139 | + [ "{accessKeyId}" ; JSONGetElement ( ~env ; "accessKeyId" ) ] ; |
| 140 | + [ "{credentialScope}" ; ~credentialScope ] ; |
| 141 | + [ "{signedHeaders}" ; ~signedHeaders ] ; |
| 142 | + [ "{signature}" ; ~signature ] |
| 143 | + ) /*substitute*/ |
| 144 | +
|
| 145 | +] ; |
| 146 | +
|
| 147 | + ~authorization |
| 148 | +
|
| 149 | +) /*let*/ |
| 150 | +``` |
| 151 | + |
| 152 | +## Sample Script (How to Request) |
| 153 | + |
| 154 | +### T02_request_request_api |
| 155 | + |
| 156 | + |
| 157 | + |
| 158 | + |
0 commit comments