Make hashed token ids url safe (#42651)

This commit changes the way token ids are hashed so that the output is
url safe without requiring encoding. This follows the pattern that we
use for document ids that are autogenerated, see UUIDs and the
associated classes for additional details.
This commit is contained in:
Jay Modi 2019-05-30 10:27:17 -06:00 committed by jaymode
parent ce30afcd01
commit 711de2f59a
No known key found for this signature in database
GPG Key ID: D859847567B3493D
6 changed files with 23 additions and 5 deletions

View File

@ -360,14 +360,14 @@ public enum Hasher {
public char[] hash(SecureString text) {
MessageDigest md = MessageDigests.sha256();
md.update(CharArrays.toUtf8Bytes(text.getChars()));
return Base64.getEncoder().encodeToString(md.digest()).toCharArray();
return Base64.getUrlEncoder().withoutPadding().encodeToString(md.digest()).toCharArray();
}
@Override
public boolean verify(SecureString text, char[] hash) {
MessageDigest md = MessageDigests.sha256();
md.update(CharArrays.toUtf8Bytes(text.getChars()));
return CharArrays.constantTimeEquals(Base64.getEncoder().encodeToString(md.digest()).toCharArray(), hash);
return CharArrays.constantTimeEquals(Base64.getUrlEncoder().withoutPadding().encodeToString(md.digest()).toCharArray(), hash);
}
},

View File

@ -181,7 +181,7 @@ public final class TokenService {
TimeValue.MINUS_ONE, Property.NodeScope);
static final String TOKEN_DOC_TYPE = "token";
private static final int HASHED_TOKEN_LENGTH = 44;
private static final int HASHED_TOKEN_LENGTH = 43;
// UUIDs are 16 bytes encoded base64 without padding, therefore the length is (16 / 3) * 4 + ((16 % 3) * 8 + 5) / 6 chars
private static final int TOKEN_LENGTH = 22;
private static final String TOKEN_DOC_ID_PREFIX = TOKEN_DOC_TYPE + "_";

View File

@ -60,7 +60,10 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import javax.crypto.SecretKey;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.time.Clock;
import java.time.Instant;
@ -70,8 +73,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.SecretKey;
import static java.time.Clock.systemUTC;
import static org.elasticsearch.repositories.ESBlobStoreTestCase.randomBytes;
import static org.elasticsearch.test.ClusterServiceUtils.setState;
@ -722,6 +723,11 @@ public class TokenServiceTests extends ESTestCase {
assertThat(authToken, Matchers.nullValue());
}
public void testHashedTokenIsUrlSafe() throws Exception {
final String hashedId = TokenService.hashTokenString(UUIDs.randomBase64UUID());
assertEquals(hashedId, URLEncoder.encode(hashedId, StandardCharsets.UTF_8.name()));
}
private TokenService createTokenService(Settings settings, Clock clock) throws GeneralSecurityException {
return new TokenService(settings, clock, client, licenseState, securityMainIndex, securityTokensIndex, clusterService);
}

View File

@ -7,6 +7,7 @@ package org.elasticsearch.upgrades;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.lucene.util.LuceneTestCase.AwaitsFix;
import org.elasticsearch.Version;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
@ -30,6 +31,7 @@ import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.hamcrest.Matchers.equalTo;
@AwaitsFix(bugUrl = "need to backport #42651")
public class TokenBackwardsCompatibilityIT extends AbstractUpgradeTestCase {
private Collection<RestClient> twoClients = null;

View File

@ -2,6 +2,8 @@
"Get the indexed token and use if to authenticate":
- skip:
features: headers
version: " - 7.99.99"
reason: "Need to backport PR #42651"
- do:
cluster.health:
@ -59,6 +61,8 @@
"Get the indexed refreshed access token and use if to authenticate":
- skip:
features: headers
version: " - 7.99.99"
reason: "Need to backport PR #42651"
- do:
get:
@ -111,6 +115,8 @@
"Get the indexed refresh token and use it to get another access token and authenticate":
- skip:
features: headers
version: " - 7.99.99"
reason: "Need to backport PR #42651"
- do:
get:

View File

@ -2,6 +2,8 @@
"Get the indexed token and use if to authenticate":
- skip:
features: headers
version: " - 8.0.0"
reason: "Need to backport PR #42651"
- do:
cluster.health:
@ -49,6 +51,8 @@
"Get the indexed refresh token and use if to get another access token and authenticate":
- skip:
features: headers
version: " - 8.0.0"
reason: "Need to backport PR #42651"
- do:
get: