Skip to content

Commit c93fbdd

Browse files
committed
Compute percentEncoded nonce once
1 parent 1ec270f commit c93fbdd

File tree

2 files changed

+20
-22
lines changed

2 files changed

+20
-22
lines changed

client/src/main/java/org/asynchttpclient/oauth/OAuthSignatureCalculatorInstance.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,43 +66,42 @@ public OAuthSignatureCalculatorInstance() throws NoSuchAlgorithmException {
6666
}
6767

6868
public void sign(ConsumerKey consumerAuth, RequestToken userAuth, Request request, RequestBuilderBase<?> requestBuilder) throws InvalidKeyException {
69-
String nonce = generateNonce();
69+
String percentEncodedNonce = generatePercentEncodedNonce();
7070
long timestamp = generateTimestamp();
71-
sign(consumerAuth, userAuth, request, requestBuilder, nonce, timestamp);
71+
sign(consumerAuth, userAuth, request, requestBuilder, percentEncodedNonce, timestamp);
7272
}
7373

74-
private String generateNonce() {
74+
private String generatePercentEncodedNonce() {
7575
ThreadLocalRandom.current().nextBytes(nonceBuffer);
7676
// let's use base64 encoding over hex, slightly more compact than hex or decimals
77-
return Base64.encode(nonceBuffer);
77+
return Utf8UrlEncoder.percentEncodeQueryElement(Base64.encode(nonceBuffer));
7878
}
7979

8080
private static long generateTimestamp() {
8181
return System.currentTimeMillis() / 1000L;
8282
}
8383

84-
void sign(ConsumerKey consumerAuth, RequestToken userAuth, Request request, RequestBuilderBase<?> requestBuilder, String nonce, long timestamp)
85-
throws InvalidKeyException {
86-
String signature = calculateSignature(consumerAuth, userAuth, request, timestamp, nonce);
87-
String headerValue = constructAuthHeader(consumerAuth, userAuth, signature, nonce, timestamp);
84+
void sign(ConsumerKey consumerAuth, RequestToken userAuth, Request request, RequestBuilderBase<?> requestBuilder, String percentEncodedNonce, long timestamp) throws InvalidKeyException {
85+
String signature = calculateSignature(consumerAuth, userAuth, request, timestamp, percentEncodedNonce);
86+
String headerValue = constructAuthHeader(consumerAuth, userAuth, signature, percentEncodedNonce, timestamp);
8887
requestBuilder.setHeader(HttpHeaderNames.AUTHORIZATION, headerValue);
8988
}
9089

91-
String calculateSignature(ConsumerKey consumerAuth, RequestToken userAuth, Request request, long oauthTimestamp, String nonce) throws InvalidKeyException {
90+
String calculateSignature(ConsumerKey consumerAuth, RequestToken userAuth, Request request, long oauthTimestamp, String percentEncodedNonce) throws InvalidKeyException {
9291

93-
StringBuilder sb = signatureBaseString(consumerAuth, userAuth, request, oauthTimestamp, nonce);
92+
StringBuilder sb = signatureBaseString(consumerAuth, userAuth, request, oauthTimestamp, percentEncodedNonce);
9493

9594
ByteBuffer rawBase = StringUtils.charSequence2ByteBuffer(sb, UTF_8);
9695
byte[] rawSignature = digest(consumerAuth, userAuth, rawBase);
9796
// and finally, base64 encoded... phew!
9897
return Base64.encode(rawSignature);
9998
}
10099

101-
StringBuilder signatureBaseString(ConsumerKey consumerAuth, RequestToken userAuth, Request request, long oauthTimestamp, String nonce) {
100+
StringBuilder signatureBaseString(ConsumerKey consumerAuth, RequestToken userAuth, Request request, long oauthTimestamp, String percentEncodedNonce) {
102101

103102
// beware: must generate first as we're using pooled StringBuilder
104103
String baseUrl = request.getUri().toBaseUrl();
105-
String encodedParams = encodedParams(consumerAuth, userAuth, oauthTimestamp, nonce, request.getFormParams(), request.getQueryParams());
104+
String encodedParams = encodedParams(consumerAuth, userAuth, oauthTimestamp, percentEncodedNonce, request.getFormParams(), request.getQueryParams());
106105

107106
StringBuilder sb = StringBuilderPool.DEFAULT.stringBuilder();
108107
sb.append(request.getMethod()); // POST / GET etc (nothing to URL encode)
@@ -115,16 +114,17 @@ StringBuilder signatureBaseString(ConsumerKey consumerAuth, RequestToken userAut
115114
return sb;
116115
}
117116

118-
private String encodedParams(ConsumerKey consumerAuth, RequestToken userAuth, long oauthTimestamp, String nonce, List<Param> formParams, List<Param> queryParams) {
117+
private String encodedParams(ConsumerKey consumerAuth, RequestToken userAuth, long oauthTimestamp, String percentEncodedNonce, List<Param> formParams, List<Param> queryParams) {
119118

120119
parameters.reset();
121120

122121
/**
123122
* List of all query and form parameters added to this request; needed for calculating request signature
124123
*/
125124
// start with standard OAuth parameters we need
126-
parameters.add(KEY_OAUTH_CONSUMER_KEY, consumerAuth.getPercentEncodedKey())
127-
.add(KEY_OAUTH_NONCE, Utf8UrlEncoder.percentEncodeQueryElement(nonce)).add(KEY_OAUTH_SIGNATURE_METHOD, OAUTH_SIGNATURE_METHOD)
125+
parameters.add(KEY_OAUTH_CONSUMER_KEY, consumerAuth.getPercentEncodedKey())//
126+
.add(KEY_OAUTH_NONCE, percentEncodedNonce)
127+
.add(KEY_OAUTH_SIGNATURE_METHOD, OAUTH_SIGNATURE_METHOD)//
128128
.add(KEY_OAUTH_TIMESTAMP, String.valueOf(oauthTimestamp));
129129
if (userAuth.getKey() != null) {
130130
parameters.add(KEY_OAUTH_TOKEN, userAuth.getPercentEncodedKey());
@@ -170,7 +170,7 @@ private byte[] digest(ConsumerKey consumerAuth, RequestToken userAuth, ByteBuffe
170170
return mac.doFinal();
171171
}
172172

173-
String constructAuthHeader(ConsumerKey consumerAuth, RequestToken userAuth, String signature, String nonce, long oauthTimestamp) {
173+
String constructAuthHeader(ConsumerKey consumerAuth, RequestToken userAuth, String signature, String percentEncodedNonce, long oauthTimestamp) {
174174
StringBuilder sb = StringBuilderPool.DEFAULT.stringBuilder();
175175
sb.append("OAuth ");
176176
sb.append(KEY_OAUTH_CONSUMER_KEY).append("=\"").append(consumerAuth.getPercentEncodedKey()).append("\", ");
@@ -184,10 +184,7 @@ String constructAuthHeader(ConsumerKey consumerAuth, RequestToken userAuth, Stri
184184
Utf8UrlEncoder.encodeAndAppendPercentEncoded(sb, signature).append("\", ");
185185
sb.append(KEY_OAUTH_TIMESTAMP).append("=\"").append(oauthTimestamp).append("\", ");
186186

187-
// also: nonce may contain things that need URL encoding (esp. when using base64):
188-
sb.append(KEY_OAUTH_NONCE).append("=\"");
189-
Utf8UrlEncoder.encodeAndAppendPercentEncoded(sb, nonce);
190-
sb.append("\", ");
187+
sb.append(KEY_OAUTH_NONCE).append("=\"").append(percentEncodedNonce).append("\", ");
191188

192189
sb.append(KEY_OAUTH_VERSION).append("=\"").append(OAUTH_VERSION_1_0).append("\"");
193190
return sb.toString();

client/src/test/java/org/asynchttpclient/oauth/OAuthSignatureCalculatorTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.asynchttpclient.Param;
2929
import org.asynchttpclient.Request;
3030
import org.asynchttpclient.RequestBuilder;
31+
import org.asynchttpclient.util.Utf8UrlEncoder;
3132
import org.testng.annotations.Test;
3233

3334
/**
@@ -82,7 +83,7 @@ private void testSignatureBaseStringWithEncodableOAuthToken(Request request) thr
8283
new RequestToken("kkk9d7dh3k39sjv7", TOKEN_SECRET),//
8384
request,//
8485
137131201,//
85-
"ZLc92RAkooZcIO/0cctl0Q==").toString();
86+
Utf8UrlEncoder.percentEncodeQueryElement("ZLc92RAkooZcIO/0cctl0Q==")).toString();
8687

8788
assertEquals(signatureBaseString, "POST&" //
8889
+ "http%3A%2F%2Fexample.com%2Frequest" //
@@ -264,7 +265,7 @@ public void testWithNullRequestToken() throws NoSuchAlgorithmException {
264265
new RequestToken(null, null),//
265266
request,//
266267
137131201,//
267-
"ZLc92RAkooZcIO/0cctl0Q==").toString();
268+
Utf8UrlEncoder.percentEncodeQueryElement("ZLc92RAkooZcIO/0cctl0Q==")).toString();
268269

269270
assertEquals(signatureBaseString, "GET&" + //
270271
"http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26" + //

0 commit comments

Comments
 (0)