|
|
@@ -6,7 +6,6 @@
|
|
|
package org.elasticsearch.xpack.security.authc;
|
|
|
|
|
|
import org.elasticsearch.ElasticsearchSecurityException;
|
|
|
-import org.elasticsearch.Version;
|
|
|
import org.elasticsearch.action.ActionListener;
|
|
|
import org.elasticsearch.action.NoShardAvailableActionException;
|
|
|
import org.elasticsearch.action.get.GetAction;
|
|
|
@@ -24,8 +23,6 @@ import org.elasticsearch.client.Client;
|
|
|
import org.elasticsearch.cluster.service.ClusterService;
|
|
|
import org.elasticsearch.common.Strings;
|
|
|
import org.elasticsearch.common.collect.Tuple;
|
|
|
-import org.elasticsearch.common.io.stream.OutputStreamStreamOutput;
|
|
|
-import org.elasticsearch.common.io.stream.StreamOutput;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.unit.TimeValue;
|
|
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
|
|
@@ -54,11 +51,7 @@ import org.junit.AfterClass;
|
|
|
import org.junit.Before;
|
|
|
import org.junit.BeforeClass;
|
|
|
|
|
|
-import java.io.ByteArrayOutputStream;
|
|
|
import java.io.IOException;
|
|
|
-import java.io.OutputStream;
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
-import java.security.GeneralSecurityException;
|
|
|
import java.time.Clock;
|
|
|
import java.time.Instant;
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
@@ -68,7 +61,6 @@ import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
|
-import javax.crypto.CipherOutputStream;
|
|
|
import javax.crypto.SecretKey;
|
|
|
|
|
|
import static java.time.Clock.systemUTC;
|
|
|
@@ -159,7 +151,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
authentication = token.getAuthentication();
|
|
|
|
|
|
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", randomFrom("Bearer ", "BEARER ", "bearer ") + tokenService.getAccessTokenAsString(token));
|
|
|
+ requestContext.putHeader("Authorization", randomFrom("Bearer ", "BEARER ", "bearer ") + tokenService.getUserTokenString(token));
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
|
|
|
@@ -206,7 +198,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
authentication = token.getAuthentication();
|
|
|
|
|
|
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + getDeprecatedAccessTokenString(tokenService, token));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(token));
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
|
|
|
@@ -227,10 +219,10 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
tokenService.createUserToken(authentication, authentication, newTokenFuture, Collections.emptyMap(), true);
|
|
|
final UserToken newToken = newTokenFuture.get().v1();
|
|
|
assertNotNull(newToken);
|
|
|
- assertNotEquals(getDeprecatedAccessTokenString(tokenService, newToken), getDeprecatedAccessTokenString(tokenService, token));
|
|
|
+ assertNotEquals(tokenService.getUserTokenString(newToken), tokenService.getUserTokenString(token));
|
|
|
|
|
|
requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + getDeprecatedAccessTokenString(tokenService, newToken));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(newToken));
|
|
|
mockGetTokenFromId(newToken, false);
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
@@ -255,7 +247,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
rotateKeys(tokenService);
|
|
|
}
|
|
|
TokenService otherTokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex,
|
|
|
- clusterService);
|
|
|
+ clusterService);
|
|
|
otherTokenService.refreshMetaData(tokenService.getTokenMetaData());
|
|
|
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
|
|
|
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
|
|
|
@@ -266,7 +258,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
authentication = token.getAuthentication();
|
|
|
|
|
|
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + getDeprecatedAccessTokenString(tokenService, token));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(token));
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
|
|
|
otherTokenService.getAndValidateToken(requestContext, future);
|
|
|
@@ -297,7 +289,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
authentication = token.getAuthentication();
|
|
|
|
|
|
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + getDeprecatedAccessTokenString(tokenService, token));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(token));
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
|
|
|
@@ -324,7 +316,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
tokenService.createUserToken(authentication, authentication, newTokenFuture, Collections.emptyMap(), true);
|
|
|
final UserToken newToken = newTokenFuture.get().v1();
|
|
|
assertNotNull(newToken);
|
|
|
- assertNotEquals(getDeprecatedAccessTokenString(tokenService, newToken), getDeprecatedAccessTokenString(tokenService, token));
|
|
|
+ assertNotEquals(tokenService.getUserTokenString(newToken), tokenService.getUserTokenString(token));
|
|
|
|
|
|
metaData = tokenService.pruneKeys(1);
|
|
|
tokenService.refreshMetaData(metaData);
|
|
|
@@ -337,7 +329,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
}
|
|
|
|
|
|
requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + getDeprecatedAccessTokenString(tokenService, newToken));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(newToken));
|
|
|
mockGetTokenFromId(newToken, false);
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
|
|
|
@@ -359,7 +351,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
authentication = token.getAuthentication();
|
|
|
|
|
|
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + getDeprecatedAccessTokenString(tokenService, token));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(token));
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
|
|
|
@@ -370,8 +362,8 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
// verify a second separate token service with its own passphrase cannot verify
|
|
|
- TokenService anotherService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex,
|
|
|
- clusterService);
|
|
|
+ TokenService anotherService = new TokenService(Settings.EMPTY, systemUTC(), client, securityIndex,
|
|
|
+ clusterService);
|
|
|
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
|
|
|
anotherService.getAndValidateToken(requestContext, future);
|
|
|
assertNull(future.get());
|
|
|
@@ -385,10 +377,10 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
|
|
|
tokenService.createUserToken(authentication, authentication, tokenFuture, Collections.emptyMap(), true);
|
|
|
UserToken token = tokenFuture.get().v1();
|
|
|
- assertThat(getDeprecatedAccessTokenString(tokenService, token), notNullValue());
|
|
|
+ assertThat(tokenService.getUserTokenString(token), notNullValue());
|
|
|
|
|
|
tokenService.clearActiveKeyCache();
|
|
|
- assertThat(getDeprecatedAccessTokenString(tokenService, token), notNullValue());
|
|
|
+ assertThat(tokenService.getUserTokenString(token), notNullValue());
|
|
|
}
|
|
|
|
|
|
public void testInvalidatedToken() throws Exception {
|
|
|
@@ -403,7 +395,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
mockGetTokenFromId(token, true);
|
|
|
|
|
|
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + tokenService.getAccessTokenAsString(token));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(token));
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
|
|
|
@@ -457,7 +449,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
authentication = token.getAuthentication();
|
|
|
|
|
|
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + tokenService.getAccessTokenAsString(token));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(token));
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
|
|
|
// the clock is still frozen, so the cookie should be valid
|
|
|
@@ -567,7 +559,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
//mockGetTokenFromId(token, false);
|
|
|
|
|
|
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
|
|
|
- requestContext.putHeader("Authorization", "Bearer " + tokenService.getAccessTokenAsString(token));
|
|
|
+ requestContext.putHeader("Authorization", "Bearer " + tokenService.getUserTokenString(token));
|
|
|
|
|
|
doAnswer(invocationOnMock -> {
|
|
|
ActionListener<GetResponse> listener = (ActionListener<GetResponse>) invocationOnMock.getArguments()[1];
|
|
|
@@ -606,7 +598,7 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
|
|
|
UserToken expired = new UserToken(authentication, Instant.now().minus(3L, ChronoUnit.DAYS));
|
|
|
mockGetTokenFromId(expired, false);
|
|
|
- String userTokenString = tokenService.getAccessTokenAsString(expired);
|
|
|
+ String userTokenString = tokenService.getUserTokenString(expired);
|
|
|
PlainActionFuture<Tuple<Authentication, Map<String, Object>>> authFuture = new PlainActionFuture<>();
|
|
|
tokenService.getAuthenticationAndMetaData(userTokenString, authFuture);
|
|
|
Authentication retrievedAuth = authFuture.actionGet().v1();
|
|
|
@@ -647,28 +639,4 @@ public class TokenServiceTests extends ESTestCase {
|
|
|
assertEquals(expected.getMetadata(), result.getMetadata());
|
|
|
assertEquals(AuthenticationType.TOKEN, result.getAuthenticationType());
|
|
|
}
|
|
|
-
|
|
|
- protected String getDeprecatedAccessTokenString(TokenService tokenService, UserToken userToken) throws IOException,
|
|
|
- GeneralSecurityException {
|
|
|
- try (ByteArrayOutputStream os = new ByteArrayOutputStream(TokenService.MINIMUM_BASE64_BYTES);
|
|
|
- OutputStream base64 = Base64.getEncoder().wrap(os);
|
|
|
- StreamOutput out = new OutputStreamStreamOutput(base64)) {
|
|
|
- out.setVersion(Version.V_7_0_0);
|
|
|
- TokenService.KeyAndCache keyAndCache = tokenService.getActiveKeyCache();
|
|
|
- Version.writeVersion(Version.V_7_0_0, out);
|
|
|
- out.writeByteArray(keyAndCache.getSalt().bytes);
|
|
|
- out.writeByteArray(keyAndCache.getKeyHash().bytes);
|
|
|
- final byte[] initializationVector = tokenService.getNewInitializationVector();
|
|
|
- out.writeByteArray(initializationVector);
|
|
|
- try (CipherOutputStream encryptedOutput =
|
|
|
- new CipherOutputStream(out, tokenService.getEncryptionCipher(initializationVector, keyAndCache, Version.V_7_0_0));
|
|
|
- StreamOutput encryptedStreamOutput = new OutputStreamStreamOutput(encryptedOutput)) {
|
|
|
- encryptedStreamOutput.setVersion(Version.V_7_0_0);
|
|
|
- encryptedStreamOutput.writeString(userToken.getId());
|
|
|
- encryptedStreamOutput.close();
|
|
|
- return new String(os.toByteArray(), StandardCharsets.UTF_8);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
}
|