1616
1717package com .akamai .edgegrid .signer ;
1818
19+ import java .net .URI ;
20+ import java .nio .charset .StandardCharsets ;
21+ import java .security .InvalidKeyException ;
22+ import java .security .MessageDigest ;
23+ import java .security .NoSuchAlgorithmException ;
24+ import java .text .SimpleDateFormat ;
25+ import java .util .ArrayList ;
26+ import java .util .Date ;
27+ import java .util .List ;
28+ import java .util .Map ;
29+ import java .util .TimeZone ;
30+ import java .util .UUID ;
31+ import java .util .regex .Matcher ;
32+ import java .util .regex .Pattern ;
33+
34+ import javax .crypto .Mac ;
35+ import javax .crypto .spec .SecretKeySpec ;
36+
37+ import org .apache .commons .codec .binary .Base64 ;
1938import org .apache .commons .lang3 .StringEscapeUtils ;
2039import org .apache .commons .lang3 .StringUtils ;
2140import org .apache .commons .lang3 .Validate ;
2746import com .akamai .edgegrid .signer .Request .RequestBuilder ;
2847import com .akamai .edgegrid .signer .exceptions .RequestSigningException ;
2948
30- import javax .crypto .Mac ;
31- import javax .crypto .spec .SecretKeySpec ;
32- import java .net .URI ;
33- import java .nio .charset .StandardCharsets ;
34- import java .security .InvalidKeyException ;
35- import java .security .MessageDigest ;
36- import java .security .NoSuchAlgorithmException ;
37- import java .text .SimpleDateFormat ;
38- import java .util .*;
39- import java .util .regex .Matcher ;
40- import java .util .regex .Pattern ;
41-
4249
4350/**
4451 * <p>
@@ -85,8 +92,6 @@ public class EdgeGridV1Signer {
8592
8693 private static final Logger log = LoggerFactory .getLogger (EdgeGridV1Signer .class );
8794
88- private final Base64 .Encoder base64 = Base64 .getEncoder ();
89-
9095 /**
9196 * Creates signer with default configuration.
9297 */
@@ -172,7 +177,7 @@ String getSignature(Request request, ClientCredential credential, long timestamp
172177 String timeStamp = formatTimeStamp (timestamp );
173178 String authData = getAuthData (credential , timeStamp , nonce );
174179 String signature = getSignature (request , credential , timeStamp , authData );
175- log .debug (String . format ( "Signature: '%s' " , signature ) );
180+ log .debug ("Signature: {} " , signature );
176181
177182 return getAuthorizationHeaderValue (authData , signature );
178183 }
@@ -181,23 +186,21 @@ private String getSignature(Request request, ClientCredential credential, String
181186 String authData ) throws RequestSigningException {
182187 String signingKey = getSigningKey (timeStamp , credential .getClientSecret ());
183188 String canonicalizedRequest = getCanonicalizedRequest (request , credential );
184- log .debug (String .format ("Canonicalized request: '%s'" ,
185- StringEscapeUtils .escapeJava (canonicalizedRequest )));
189+ log .debug ("Canonicalized request: {}" , StringEscapeUtils .escapeJava (canonicalizedRequest ));
186190 String dataToSign = getDataToSign (canonicalizedRequest , authData );
187- log .debug (String .format ("Data to sign: '%s'" ,
188- StringEscapeUtils .escapeJava (dataToSign )));
191+ log .debug ("Data to sign: {}" , StringEscapeUtils .escapeJava (dataToSign ));
189192
190193 return signAndEncode (dataToSign , signingKey );
191194 }
192195
193196 private String signAndEncode (String stringToSign , String signingKey ) throws RequestSigningException {
194197 byte [] signatureBytes = sign (stringToSign , signingKey );
195- return base64 . encodeToString (signatureBytes );
198+ return Base64 . encodeBase64String (signatureBytes );
196199 }
197200
198201 private String getSigningKey (String timeStamp , String clientSecret ) throws RequestSigningException {
199202 byte [] signingKeyBytes = sign (timeStamp , clientSecret );
200- return base64 . encodeToString (signingKeyBytes );
203+ return Base64 . encodeBase64String (signingKeyBytes );
201204 }
202205
203206 private String getDataToSign (String canonicalizedRequest , String authData ) {
@@ -236,15 +239,15 @@ private String getCanonicalizedRequest(Request request, ClientCredential credent
236239 sb .append (request .getMethod ().toUpperCase ());
237240 sb .append ('\t' );
238241
239- String scheme = StringUtils .defaultString (request .getUriWithQuery ().getScheme (), "https" );
242+ String scheme = StringUtils .defaultString (request .getUri ().getScheme (), "https" );
240243 sb .append (scheme .toLowerCase ());
241244 sb .append ('\t' );
242245
243246 String host = credential .getHost ();
244247 sb .append (host .toLowerCase ());
245248 sb .append ('\t' );
246249
247- String relativePath = getRelativePathWithQuery (request .getUriWithQuery ());
250+ String relativePath = getRelativePathWithQuery (request .getUri ());
248251 String relativeUrl = canonicalizeUri (relativePath );
249252 sb .append (relativeUrl );
250253 sb .append ('\t' );
@@ -272,6 +275,7 @@ private byte[] getHash(byte[] requestBody, int offset, int len) throws RequestSi
272275
273276 private String canonicalizeHeaders (Map <String , String > requestHeaders , ClientCredential credential ) {
274277 List <String > headers = new ArrayList <>();
278+ // NOTE: Headers are expected to be in order. ClientCredential#headersToSign is a TreeSet.
275279 for (String headerName : credential .getHeadersToSign ()) {
276280 String headerValue = requestHeaders .get (headerName );
277281 if (StringUtils .isBlank (headerValue )) {
@@ -304,18 +308,21 @@ private String getContentHash(String requestMethod, byte[] requestBody, int maxB
304308
305309 int lengthToHash = requestBody .length ;
306310 if (lengthToHash > maxBodySize ) {
307- log .info (String .format ("Content length '%d' is larger than the max '%d'. " +
308- "Using first '%d' bytes for computing the hash." , lengthToHash , maxBodySize , maxBodySize ));
311+ log .info ("Content length '{}' exceeds signing length of '{}'. Less than the entire message will be signed." ,
312+ lengthToHash ,
313+ maxBodySize );
309314 lengthToHash = maxBodySize ;
310315 } else {
311- log .debug (String .format ("Content (Base64): %s" , base64 .encodeToString (requestBody )));
316+ if (log .isTraceEnabled ()) {
317+ log .trace ("Content (Base64): {}" , Base64 .encodeBase64String (requestBody ));
318+ }
312319 }
313320
314321 byte [] digestBytes = getHash (requestBody , 0 , lengthToHash );
315- log .debug (String . format ( "Content hash (Base64): %s " , base64 . encodeToString (digestBytes ) ));
322+ log .debug ("Content hash (Base64): {} " , Base64 . encodeBase64String (digestBytes ));
316323
317324 // (mgawinec) I removed support for non-retryable content, that used to reset the content for downstream handlers
318- return base64 . encodeToString (digestBytes );
325+ return Base64 . encodeBase64String (digestBytes );
319326 }
320327
321328}
0 commit comments