1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * * Neither the name of Google LLC nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package com.google.auth.oauth2; 33 34 import static org.junit.Assert.assertEquals; 35 36 import com.google.api.client.json.GenericJson; 37 import com.google.api.client.json.JsonFactory; 38 import com.google.api.client.json.JsonObjectParser; 39 import java.io.IOException; 40 import java.io.InputStream; 41 import java.net.URI; 42 import java.nio.charset.StandardCharsets; 43 import java.util.HashMap; 44 import java.util.Locale; 45 import java.util.Map; 46 import org.junit.Before; 47 import org.junit.Test; 48 49 /** 50 * Tests for {@link AwsRequestSigner}. 51 * 52 * <p>Examples of sigv4 signed requests: 53 * https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html 54 */ 55 public class AwsRequestSignerTest { 56 57 private static final String DATE = "Mon, 09 Sep 2011 23:36:00 GMT"; 58 private static final String X_AMZ_DATE = "20200811T065522Z"; 59 60 private static final AwsSecurityCredentials BOTOCORE_CREDENTIALS = 61 new AwsSecurityCredentials( 62 "AKIDEXAMPLE", "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", /* token= */ null); 63 64 private AwsSecurityCredentials awsSecurityCredentials; 65 66 @Before setUp()67 public void setUp() throws IOException { 68 // Required for date parsing when run in different Locales 69 Locale.setDefault(Locale.US); 70 awsSecurityCredentials = retrieveAwsSecurityCredentials(); 71 } 72 73 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-vanilla.req 74 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-vanilla.sreq 75 @Test sign_getHost()76 public void sign_getHost() { 77 String url = "https://host.foo.com"; 78 79 Map<String, String> headers = new HashMap<>(); 80 headers.put("date", DATE); 81 82 AwsRequestSigner signer = 83 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "GET", url, "us-east-1") 84 .setAdditionalHeaders(headers) 85 .build(); 86 87 AwsRequestSignature signature = signer.sign(); 88 89 String expectedSignature = "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470"; 90 String expectedAuthHeader = 91 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 92 + "aws4_request, SignedHeaders=date;host, Signature=" 93 + expectedSignature; 94 95 assertEquals(expectedSignature, signature.getSignature()); 96 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 97 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 98 assertEquals(DATE, signature.getDate()); 99 assertEquals("GET", signature.getHttpMethod()); 100 assertEquals("us-east-1", signature.getRegion()); 101 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 102 } 103 104 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-relative-relative.req 105 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-relative-relative.sreq 106 @Test sign_getHostRelativePath()107 public void sign_getHostRelativePath() { 108 String url = "https://host.foo.com/foo/bar/../.."; 109 110 Map<String, String> headers = new HashMap<>(); 111 headers.put("date", DATE); 112 113 AwsRequestSigner signer = 114 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "GET", url, "us-east-1") 115 .setAdditionalHeaders(headers) 116 .build(); 117 118 AwsRequestSignature signature = signer.sign(); 119 120 String expectedSignature = "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470"; 121 String expectedAuthHeader = 122 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 123 + "aws4_request, SignedHeaders=date;host, Signature=" 124 + expectedSignature; 125 126 assertEquals(expectedSignature, signature.getSignature()); 127 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 128 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 129 assertEquals(DATE, signature.getDate()); 130 assertEquals("GET", signature.getHttpMethod()); 131 assertEquals("us-east-1", signature.getRegion()); 132 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 133 } 134 135 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-slash-dot-slash.req 136 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-slash-dot-slash.sreq 137 @Test sign_getHostInvalidPath()138 public void sign_getHostInvalidPath() { 139 String url = "https://host.foo.com/./"; 140 141 Map<String, String> headers = new HashMap<>(); 142 headers.put("date", DATE); 143 144 AwsRequestSigner signer = 145 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "GET", url, "us-east-1") 146 .setAdditionalHeaders(headers) 147 .build(); 148 149 AwsRequestSignature signature = signer.sign(); 150 151 String expectedSignature = "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470"; 152 String expectedAuthHeader = 153 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 154 + "aws4_request, SignedHeaders=date;host, Signature=" 155 + expectedSignature; 156 157 assertEquals(expectedSignature, signature.getSignature()); 158 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 159 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 160 assertEquals(DATE, signature.getDate()); 161 assertEquals("GET", signature.getHttpMethod()); 162 assertEquals("us-east-1", signature.getRegion()); 163 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 164 } 165 166 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-slash-pointless-dot.req 167 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-slash-pointless-dot.sreq 168 @Test sign_getHostDotPath()169 public void sign_getHostDotPath() { 170 String url = "https://host.foo.com/./foo"; 171 172 Map<String, String> headers = new HashMap<>(); 173 headers.put("date", DATE); 174 175 AwsRequestSigner signer = 176 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "GET", url, "us-east-1") 177 .setAdditionalHeaders(headers) 178 .build(); 179 180 AwsRequestSignature signature = signer.sign(); 181 182 String expectedSignature = "910e4d6c9abafaf87898e1eb4c929135782ea25bb0279703146455745391e63a"; 183 String expectedAuthHeader = 184 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 185 + "aws4_request, SignedHeaders=date;host, Signature=" 186 + expectedSignature; 187 188 assertEquals(expectedSignature, signature.getSignature()); 189 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 190 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 191 assertEquals(DATE, signature.getDate()); 192 assertEquals("GET", signature.getHttpMethod()); 193 assertEquals("us-east-1", signature.getRegion()); 194 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 195 } 196 197 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-utf8.req 198 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-utf8.sreq 199 @Test sign_getHostUtf8Path()200 public void sign_getHostUtf8Path() { 201 String url = "https://host.foo.com/%E1%88%B4"; 202 203 Map<String, String> headers = new HashMap<>(); 204 headers.put("date", DATE); 205 206 AwsRequestSigner signer = 207 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "GET", url, "us-east-1") 208 .setAdditionalHeaders(headers) 209 .build(); 210 211 AwsRequestSignature signature = signer.sign(); 212 213 String expectedSignature = "8d6634c189aa8c75c2e51e106b6b5121bed103fdb351f7d7d4381c738823af74"; 214 String expectedAuthHeader = 215 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 216 + "aws4_request, SignedHeaders=date;host, Signature=" 217 + expectedSignature; 218 219 assertEquals(expectedSignature, signature.getSignature()); 220 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 221 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 222 assertEquals(DATE, signature.getDate()); 223 assertEquals("GET", signature.getHttpMethod()); 224 assertEquals("us-east-1", signature.getRegion()); 225 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 226 } 227 228 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-vanilla-query-order-key-case.req 229 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-vanilla-query-order-key-case.sreq 230 @Test sign_getHostDuplicateQueryParam()231 public void sign_getHostDuplicateQueryParam() { 232 String url = "https://host.foo.com/?foo=Zoo&foo=aha"; 233 234 Map<String, String> headers = new HashMap<>(); 235 headers.put("date", DATE); 236 237 AwsRequestSigner signer = 238 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "GET", url, "us-east-1") 239 .setAdditionalHeaders(headers) 240 .build(); 241 242 AwsRequestSignature signature = signer.sign(); 243 244 String expectedSignature = "be7148d34ebccdc6423b19085378aa0bee970bdc61d144bd1a8c48c33079ab09"; 245 String expectedAuthHeader = 246 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 247 + "aws4_request, SignedHeaders=date;host, Signature=" 248 + expectedSignature; 249 250 assertEquals(expectedSignature, signature.getSignature()); 251 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 252 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 253 assertEquals(DATE, signature.getDate()); 254 assertEquals("GET", signature.getHttpMethod()); 255 assertEquals("us-east-1", signature.getRegion()); 256 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 257 } 258 259 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/post-header-key-sort.req 260 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/post-header-key-sort.sreq 261 @Test sign_postWithUpperCaseHeaderKey()262 public void sign_postWithUpperCaseHeaderKey() { 263 String url = "https://host.foo.com/"; 264 String headerKey = "ZOO"; 265 String headerValue = "zoobar"; 266 267 Map<String, String> headers = new HashMap<>(); 268 headers.put("date", DATE); 269 headers.put(headerKey, headerValue); 270 271 AwsRequestSigner signer = 272 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "POST", url, "us-east-1") 273 .setAdditionalHeaders(headers) 274 .build(); 275 276 AwsRequestSignature signature = signer.sign(); 277 278 String expectedSignature = "b7a95a52518abbca0964a999a880429ab734f35ebbf1235bd79a5de87756dc4a"; 279 String expectedAuthHeader = 280 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 281 + "aws4_request, SignedHeaders=date;host;zoo, Signature=" 282 + expectedSignature; 283 284 assertEquals(expectedSignature, signature.getSignature()); 285 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 286 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 287 assertEquals(DATE, signature.getDate()); 288 assertEquals("POST", signature.getHttpMethod()); 289 assertEquals("us-east-1", signature.getRegion()); 290 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 291 assertEquals(headerValue, signature.getCanonicalHeaders().get(headerKey.toLowerCase())); 292 } 293 294 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/post-header-value-case.req 295 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/post-header-value-case.sreq 296 @Test sign_postWithUpperCaseHeaderValue()297 public void sign_postWithUpperCaseHeaderValue() { 298 String url = "https://host.foo.com/"; 299 String headerKey = "zoo"; 300 String headerValue = "ZOOBAR"; 301 302 Map<String, String> headers = new HashMap<>(); 303 headers.put("date", DATE); 304 headers.put("zoo", "ZOOBAR"); 305 306 AwsRequestSigner signer = 307 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "POST", url, "us-east-1") 308 .setAdditionalHeaders(headers) 309 .build(); 310 311 AwsRequestSignature signature = signer.sign(); 312 313 String expectedSignature = "273313af9d0c265c531e11db70bbd653f3ba074c1009239e8559d3987039cad7"; 314 String expectedAuthHeader = 315 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 316 + "aws4_request, SignedHeaders=date;host;zoo, Signature=" 317 + expectedSignature; 318 319 assertEquals(expectedSignature, signature.getSignature()); 320 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 321 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 322 assertEquals(DATE, signature.getDate()); 323 assertEquals("POST", signature.getHttpMethod()); 324 assertEquals("us-east-1", signature.getRegion()); 325 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 326 assertEquals(headerValue, signature.getCanonicalHeaders().get(headerKey.toLowerCase())); 327 } 328 329 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-header-value-trim.req 330 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/get-header-value-trim.sreq 331 @Test sign_postWithHeader()332 public void sign_postWithHeader() { 333 String url = "https://host.foo.com/"; 334 String headerKey = "p"; 335 String headerValue = "phfft"; 336 337 Map<String, String> headers = new HashMap<>(); 338 headers.put("date", DATE); 339 headers.put(headerKey, headerValue); 340 341 AwsRequestSigner signer = 342 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "POST", url, "us-east-1") 343 .setAdditionalHeaders(headers) 344 .build(); 345 346 AwsRequestSignature signature = signer.sign(); 347 348 String expectedSignature = "debf546796015d6f6ded8626f5ce98597c33b47b9164cf6b17b4642036fcb592"; 349 String expectedAuthHeader = 350 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 351 + "aws4_request, SignedHeaders=date;host;p, Signature=" 352 + expectedSignature; 353 354 assertEquals(expectedSignature, signature.getSignature()); 355 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 356 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 357 assertEquals(DATE, signature.getDate()); 358 assertEquals("POST", signature.getHttpMethod()); 359 assertEquals("us-east-1", signature.getRegion()); 360 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 361 assertEquals(headerValue, signature.getCanonicalHeaders().get(headerKey.toLowerCase())); 362 } 363 364 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/post-x-www-form-urlencoded.req 365 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/post-x-www-form-urlencoded.sreq 366 @Test sign_postWithBodyNoCustomHeaders()367 public void sign_postWithBodyNoCustomHeaders() { 368 String url = "https://host.foo.com/"; 369 String headerKey = "Content-Type"; 370 String headerValue = "application/x-www-form-urlencoded"; 371 372 Map<String, String> headers = new HashMap<>(); 373 headers.put("date", DATE); 374 headers.put(headerKey, headerValue); 375 376 AwsRequestSigner signer = 377 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "POST", url, "us-east-1") 378 .setAdditionalHeaders(headers) 379 .setRequestPayload("foo=bar") 380 .build(); 381 382 AwsRequestSignature signature = signer.sign(); 383 384 String expectedSignature = "5a15b22cf462f047318703b92e6f4f38884e4a7ab7b1d6426ca46a8bd1c26cbc"; 385 String expectedAuthHeader = 386 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 387 + "aws4_request, SignedHeaders=content-type;date;host, Signature=" 388 + expectedSignature; 389 390 assertEquals(expectedSignature, signature.getSignature()); 391 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 392 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 393 assertEquals(DATE, signature.getDate()); 394 assertEquals("POST", signature.getHttpMethod()); 395 assertEquals("us-east-1", signature.getRegion()); 396 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 397 assertEquals(headerValue, signature.getCanonicalHeaders().get(headerKey.toLowerCase())); 398 } 399 400 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/post-vanilla-query.req 401 // https://github.com/boto/botocore/blob/879f8440a4e9ace5d3cf145ce8b3d5e5ffb892ef/tests/unit/auth/aws4_testsuite/post-vanilla-query.sreq 402 @Test sign_postWithQueryString()403 public void sign_postWithQueryString() { 404 String url = "https://host.foo.com/?foo=bar"; 405 406 Map<String, String> headers = new HashMap<>(); 407 headers.put("date", DATE); 408 409 AwsRequestSigner signer = 410 AwsRequestSigner.newBuilder(BOTOCORE_CREDENTIALS, "POST", url, "us-east-1") 411 .setAdditionalHeaders(headers) 412 .build(); 413 414 AwsRequestSignature signature = signer.sign(); 415 416 String expectedSignature = "b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92"; 417 String expectedAuthHeader = 418 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/" 419 + "aws4_request, SignedHeaders=date;host, Signature=" 420 + expectedSignature; 421 422 assertEquals(expectedSignature, signature.getSignature()); 423 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 424 assertEquals(BOTOCORE_CREDENTIALS, signature.getSecurityCredentials()); 425 assertEquals(DATE, signature.getDate()); 426 assertEquals("POST", signature.getHttpMethod()); 427 assertEquals("us-east-1", signature.getRegion()); 428 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 429 } 430 431 @Test sign_getDescribeRegions()432 public void sign_getDescribeRegions() { 433 String url = "https://ec2.us-east-2.amazonaws.com?Action=DescribeRegions&Version=2013-10-15"; 434 435 Map<String, String> additionalHeaders = new HashMap<>(); 436 additionalHeaders.put("x-amz-date", X_AMZ_DATE); 437 438 AwsRequestSigner signer = 439 AwsRequestSigner.newBuilder(awsSecurityCredentials, "GET", url, "us-east-2") 440 .setAdditionalHeaders(additionalHeaders) 441 .build(); 442 443 AwsRequestSignature signature = signer.sign(); 444 445 String expectedSignature = "631ea80cddfaa545fdadb120dc92c9f18166e38a5c47b50fab9fce476e022855"; 446 String expectedAuthHeader = 447 "AWS4-HMAC-SHA256 Credential=" 448 + awsSecurityCredentials.getAccessKeyId() 449 + "/20200811/us-east-2/ec2/" 450 + "aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=" 451 + expectedSignature; 452 453 assertEquals(expectedSignature, signature.getSignature()); 454 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 455 assertEquals(awsSecurityCredentials, signature.getSecurityCredentials()); 456 assertEquals(X_AMZ_DATE, signature.getDate()); 457 assertEquals("GET", signature.getHttpMethod()); 458 assertEquals("us-east-2", signature.getRegion()); 459 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 460 } 461 462 @Test sign_postGetCallerIdentity()463 public void sign_postGetCallerIdentity() { 464 String url = "https://sts.us-east-2.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"; 465 466 Map<String, String> additionalHeaders = new HashMap<>(); 467 additionalHeaders.put("x-amz-date", X_AMZ_DATE); 468 469 AwsRequestSigner signer = 470 AwsRequestSigner.newBuilder(awsSecurityCredentials, "POST", url, "us-east-2") 471 .setAdditionalHeaders(additionalHeaders) 472 .build(); 473 474 AwsRequestSignature signature = signer.sign(); 475 476 String expectedSignature = "73452984e4a880ffdc5c392355733ec3f5ba310d5e0609a89244440cadfe7a7a"; 477 String expectedAuthHeader = 478 "AWS4-HMAC-SHA256 Credential=" 479 + awsSecurityCredentials.getAccessKeyId() 480 + "/20200811/us-east-2/sts/" 481 + "aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=" 482 + expectedSignature; 483 484 assertEquals(expectedSignature, signature.getSignature()); 485 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 486 assertEquals(awsSecurityCredentials, signature.getSecurityCredentials()); 487 assertEquals(X_AMZ_DATE, signature.getDate()); 488 assertEquals("POST", signature.getHttpMethod()); 489 assertEquals("us-east-2", signature.getRegion()); 490 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 491 } 492 493 @Test sign_postGetCallerIdentityNoToken()494 public void sign_postGetCallerIdentityNoToken() { 495 String url = "https://sts.us-east-2.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"; 496 497 AwsSecurityCredentials awsSecurityCredentialsWithoutToken = 498 new AwsSecurityCredentials( 499 awsSecurityCredentials.getAccessKeyId(), 500 awsSecurityCredentials.getSecretAccessKey(), 501 /* token= */ null); 502 503 Map<String, String> additionalHeaders = new HashMap<>(); 504 additionalHeaders.put("x-amz-date", X_AMZ_DATE); 505 506 AwsRequestSigner signer = 507 AwsRequestSigner.newBuilder(awsSecurityCredentialsWithoutToken, "POST", url, "us-east-2") 508 .setAdditionalHeaders(additionalHeaders) 509 .build(); 510 511 AwsRequestSignature signature = signer.sign(); 512 513 String expectedSignature = "d095ba304919cd0d5570ba8a3787884ee78b860f268ed040ba23831d55536d56"; 514 String expectedAuthHeader = 515 "AWS4-HMAC-SHA256 Credential=" 516 + awsSecurityCredentials.getAccessKeyId() 517 + "/20200811/us-east-2/sts/" 518 + "aws4_request, SignedHeaders=host;x-amz-date, Signature=" 519 + expectedSignature; 520 521 assertEquals(expectedSignature, signature.getSignature()); 522 assertEquals(expectedAuthHeader, signature.getAuthorizationHeader()); 523 assertEquals(awsSecurityCredentialsWithoutToken, signature.getSecurityCredentials()); 524 assertEquals(X_AMZ_DATE, signature.getDate()); 525 assertEquals("POST", signature.getHttpMethod()); 526 assertEquals("us-east-2", signature.getRegion()); 527 assertEquals(URI.create(url).normalize().toString(), signature.getUrl()); 528 } 529 retrieveAwsSecurityCredentials()530 public AwsSecurityCredentials retrieveAwsSecurityCredentials() throws IOException { 531 InputStream stream = 532 AwsRequestSignerTest.class 533 .getClassLoader() 534 .getResourceAsStream("aws_security_credentials.json"); 535 536 JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; 537 JsonObjectParser parser = new JsonObjectParser(jsonFactory); 538 539 GenericJson json = parser.parseAndClose(stream, StandardCharsets.UTF_8, GenericJson.class); 540 541 String accessKeyId = (String) json.get("AccessKeyId"); 542 String secretAccessKey = (String) json.get("SecretAccessKey"); 543 String awsToken = (String) json.get("Token"); 544 545 return new AwsSecurityCredentials(accessKeyId, secretAccessKey, awsToken); 546 } 547 } 548