aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@oath.com>2018-07-09 15:13:33 +0200
committerBjørn Christian Seime <bjorncs@oath.com>2018-07-09 15:22:53 +0200
commit3588ab015c45e5e8682e9a9299cabec25937d9d8 (patch)
tree4911645bf82062d85402ba2329358914733e812e /controller-server
parent257bfcde6220c40e7ceab46d1f5b5ab8c5e650a0 (diff)
Move NTokenValidator to vespa-athenz + load pub keys from file
- Move NTokenValidator from controller-server to vespa-athenz - Remodel ZmsKeystore as AthenzTruststore - Use file-backed truststore on controller (replaces download of public keys) - Remove ZmsClient.getPublicKey/getPublicKeys
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilter.java19
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidator.java81
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/UserAuthWithAthenzPrincipalFilter.java9
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsClientImpl.java36
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsKeystoreImpl.java120
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java12
-rw-r--r--controller-server/src/main/resources/configdefinitions/athenz.def3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java18
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzTestUtils.java22
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java100
10 files changed, 22 insertions, 398 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilter.java
index 5166f53c6d2..b7ede7635c6 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilter.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilter.java
@@ -9,15 +9,16 @@ import com.yahoo.jdisc.http.filter.security.cors.CorsRequestFilterBase;
import com.yahoo.vespa.athenz.api.AthenzPrincipal;
import com.yahoo.vespa.athenz.api.NToken;
import com.yahoo.vespa.athenz.utils.AthenzIdentities;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsKeystore;
+import com.yahoo.vespa.athenz.utils.ntoken.AthenzConfTruststore;
+import com.yahoo.vespa.athenz.utils.ntoken.NTokenValidator;
import com.yahoo.vespa.hosted.controller.athenz.config.AthenzConfig;
+import java.nio.file.Paths;
import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
-import java.util.concurrent.Executor;
/**
@@ -30,31 +31,23 @@ import java.util.concurrent.Executor;
*
* @author bjorncs
*/
-// TODO bjorncs: Move this class to vespa-athenz bundle
+// TODO bjorncs: Move this class to jdisc-security-filters bundle
public class AthenzPrincipalFilter extends CorsRequestFilterBase {
private final NTokenValidator validator;
private final String principalTokenHeader;
- /**
- * @param executor to preload the ZMS public keys with
- */
@Inject
- public AthenzPrincipalFilter(ZmsKeystore zmsKeystore,
- Executor executor,
- AthenzConfig athenzConfig,
- CorsFilterConfig corsConfig) {
- this(new NTokenValidator(zmsKeystore), executor, athenzConfig.principalHeaderName(), new HashSet<>(corsConfig.allowedUrls()));
+ public AthenzPrincipalFilter(AthenzConfig athenzConfig, CorsFilterConfig corsConfig) {
+ this(new NTokenValidator(Paths.get(athenzConfig.athenzConfFile())), athenzConfig.principalHeaderName(), new HashSet<>(corsConfig.allowedUrls()));
}
AthenzPrincipalFilter(NTokenValidator validator,
- Executor executor,
String principalTokenHeader,
Set<String> corsAllowedUrls) {
super(corsAllowedUrls);
this.validator = validator;
this.principalTokenHeader = principalTokenHeader;
- executor.execute(validator::preloadPublicKeys);
}
@Override
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidator.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidator.java
deleted file mode 100644
index 4dcca519058..00000000000
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidator.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.athenz.filter;
-
-import com.yahoo.athenz.auth.token.PrincipalToken;
-import com.yahoo.log.LogLevel;
-import com.yahoo.vespa.athenz.api.AthenzDomain;
-import com.yahoo.vespa.athenz.api.AthenzPrincipal;
-import com.yahoo.vespa.athenz.api.NToken;
-import com.yahoo.vespa.athenz.utils.AthenzIdentities;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.InvalidTokenException;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsKeystore;
-
-import java.security.PublicKey;
-import java.time.Duration;
-import java.util.Optional;
-import java.util.logging.Logger;
-
-import static com.yahoo.vespa.athenz.utils.AthenzIdentities.ZMS_ATHENZ_SERVICE;
-
-
-/**
- * Validates the content of an NToken:
- * 1) Verifies that the token is signed by the sys.auth.zms service (by validating the signature)
- * 2) Verifies that the token is not expired
- *
- * @author bjorncs
- */
-// TODO Move to vespa-athenz
-class NTokenValidator {
-
- // Max allowed skew in token timestamp (only for creation, not expiry timestamp)
- private static final long ALLOWED_TIMESTAMP_OFFSET = Duration.ofMinutes(5).getSeconds();
-
- private static final Logger log = Logger.getLogger(NTokenValidator.class.getName());
-
- private final ZmsKeystore keystore;
-
- NTokenValidator(ZmsKeystore keystore) {
- this.keystore = keystore;
- }
-
- void preloadPublicKeys() {
- keystore.preloadKeys(ZMS_ATHENZ_SERVICE);
- }
-
- AthenzPrincipal validate(NToken token) throws InvalidTokenException {
- PrincipalToken principalToken = new PrincipalToken(token.getRawToken());
- PublicKey zmsPublicKey = getPublicKey(principalToken.getKeyId())
- .orElseThrow(() -> new InvalidTokenException("NToken has an unknown keyId"));
- validateSignatureAndExpiration(principalToken, zmsPublicKey);
- return new AthenzPrincipal(
- AthenzIdentities.from(
- new AthenzDomain(principalToken.getDomain()),
- principalToken.getName()),
- token);
- }
-
- private Optional<PublicKey> getPublicKey(String keyId) throws InvalidTokenException {
- try {
- return keystore.getPublicKey(ZMS_ATHENZ_SERVICE, keyId);
- } catch (Exception e) {
- logDebug(e.getMessage());
- throw new InvalidTokenException("Failed to retrieve public key");
- }
- }
-
- private static void validateSignatureAndExpiration(PrincipalToken token,
- PublicKey zmsPublicKey) throws InvalidTokenException {
- StringBuilder errorMessageBuilder = new StringBuilder();
- if (!token.validate(zmsPublicKey, (int) ALLOWED_TIMESTAMP_OFFSET, true, errorMessageBuilder)) {
- String message = "NToken is expired or has invalid signature: " + errorMessageBuilder.toString();
- logDebug(message);
- throw new InvalidTokenException(message);
- }
- }
-
- private static void logDebug(String message) {
- log.log(LogLevel.DEBUG, "Failed to validate NToken: " + message);
- }
-
-}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/UserAuthWithAthenzPrincipalFilter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/UserAuthWithAthenzPrincipalFilter.java
index b801c038bd8..0aa5c89c971 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/UserAuthWithAthenzPrincipalFilter.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/filter/UserAuthWithAthenzPrincipalFilter.java
@@ -10,13 +10,11 @@ import com.yahoo.vespa.athenz.api.AthenzPrincipal;
import com.yahoo.vespa.athenz.api.AthenzUser;
import com.yahoo.vespa.athenz.api.NToken;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsKeystore;
import com.yahoo.vespa.hosted.controller.athenz.config.AthenzConfig;
import com.yahoo.yolean.chain.After;
import java.security.Principal;
import java.util.Optional;
-import java.util.concurrent.Executor;
import java.util.logging.Logger;
import java.util.stream.Stream;
@@ -38,11 +36,8 @@ public class UserAuthWithAthenzPrincipalFilter extends AthenzPrincipalFilter {
private final String principalHeaderName;
@Inject
- public UserAuthWithAthenzPrincipalFilter(ZmsKeystore zmsKeystore,
- Executor executor,
- AthenzConfig athenzConfig,
- CorsFilterConfig corsConfig) {
- super(zmsKeystore, executor, athenzConfig, corsConfig);
+ public UserAuthWithAthenzPrincipalFilter(AthenzConfig athenzConfig, CorsFilterConfig corsConfig) {
+ super(athenzConfig, corsConfig);
this.userAuthenticationPassThruAttribute = athenzConfig.userAuthenticationPassThruAttribute();
this.principalHeaderName = athenzConfig.principalHeaderName();
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsClientImpl.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsClientImpl.java
index 67191d4c09d..6179d9891fd 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsClientImpl.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsClientImpl.java
@@ -1,22 +1,18 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.athenz.impl;
-import com.yahoo.athenz.auth.util.Crypto;
import com.yahoo.athenz.zms.DomainList;
import com.yahoo.athenz.zms.ProviderResourceGroupRoles;
-import com.yahoo.athenz.zms.PublicKeyEntry;
-import com.yahoo.athenz.zms.ServiceIdentity;
import com.yahoo.athenz.zms.Tenancy;
import com.yahoo.athenz.zms.TenantRoleAction;
import com.yahoo.athenz.zms.ZMSClient;
import com.yahoo.athenz.zms.ZMSClientException;
import com.yahoo.log.LogLevel;
-import com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId;
import com.yahoo.vespa.athenz.api.AthenzDomain;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.ApplicationAction;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
-import com.yahoo.vespa.athenz.api.AthenzPublicKey;
import com.yahoo.vespa.athenz.api.AthenzService;
+import com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId;
+import com.yahoo.vespa.hosted.controller.api.integration.athenz.ApplicationAction;
import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsClient;
import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsException;
import com.yahoo.vespa.hosted.controller.athenz.config.AthenzConfig;
@@ -130,28 +126,6 @@ public class ZmsClientImpl implements ZmsClient {
});
}
- @Override
- public AthenzPublicKey getPublicKey(AthenzService service, String keyId) {
- log("getPublicKeyEntry(domain=%s, service=%s, keyId=%s)", service.getDomain().getName(), service.getName(), keyId);
- return getOrThrow(() -> {
- PublicKeyEntry entry = zmsClient.getPublicKeyEntry(service.getDomain().getName(), service.getName(), keyId);
- return fromYbase64EncodedKey(entry.getKey(), keyId);
- });
- }
-
- @Override
- public List<AthenzPublicKey> getPublicKeys(AthenzService service) {
- log("getServiceIdentity(domain=%s, service=%s)", service.getDomain().getName(), service.getName());
- return getOrThrow(() -> {
- ServiceIdentity serviceIdentity = zmsClient.getServiceIdentity(service.getDomain().getName(), service.getName());
- return toAthenzPublicKeys(serviceIdentity.getPublicKeys());
- });
- }
-
- private static AthenzPublicKey fromYbase64EncodedKey(String encodedKey, String keyId) {
- return new AthenzPublicKey(Crypto.loadPublicKey(Crypto.ybase64DecodeString(encodedKey)), keyId);
- }
-
private static List<TenantRoleAction> createTenantRoleActions() {
return Arrays.stream(ApplicationAction.values())
.map(action -> new TenantRoleAction().setAction(action.name()).setRole(action.roleName))
@@ -162,12 +136,6 @@ public class ZmsClientImpl implements ZmsClient {
return domains.stream().map(AthenzDomain::new).collect(toList());
}
- private static List<AthenzPublicKey> toAthenzPublicKeys(List<PublicKeyEntry> publicKeys) {
- return publicKeys.stream()
- .map(entry -> fromYbase64EncodedKey(entry.getKey(), entry.getId()))
- .collect(toList());
- }
-
private boolean hasAccess(String action, String resource, AthenzIdentity identity) {
log("getAccess(action=%s, resource=%s, principal=%s)", action, resource, identity);
return getOrThrow(
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsKeystoreImpl.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsKeystoreImpl.java
deleted file mode 100644
index 4b194651439..00000000000
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/ZmsKeystoreImpl.java
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.athenz.impl;
-
-import com.google.inject.Inject;
-import com.yahoo.log.LogLevel;
-import com.yahoo.vespa.athenz.api.AthenzPublicKey;
-import com.yahoo.vespa.athenz.api.AthenzService;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzClientFactory;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsException;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsKeystore;
-
-import java.security.PublicKey;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
-
-/**
- * Downloads and caches public keys for Athens services.
- *
- * @author bjorncs
- */
-public class ZmsKeystoreImpl implements ZmsKeystore {
- private static final Logger log = Logger.getLogger(ZmsKeystoreImpl.class.getName());
-
- private final Map<FullKeyId, PublicKey> cachedKeys = new ConcurrentHashMap<>();
- private final AthenzClientFactory athenzClientFactory;
-
- @Inject
- public ZmsKeystoreImpl(AthenzClientFactory factory) {
- this.athenzClientFactory = factory;
- }
-
- @Override
- public Optional<PublicKey> getPublicKey(AthenzService service, String keyId) {
- FullKeyId fullKeyId = new FullKeyId(service, keyId);
- PublicKey cachedKey = cachedKeys.get(fullKeyId);
- if (cachedKey != null) {
- return Optional.of(cachedKey);
- }
- Optional<PublicKey> downloadedKey = downloadPublicKey(fullKeyId);
- downloadedKey.ifPresent(key -> {
- log.log(LogLevel.INFO, "Adding key " + fullKeyId + " to the cache");
- cachedKeys.put(fullKeyId, key);
- });
- return downloadedKey;
- }
-
- @Override
- public void preloadKeys(AthenzService service) {
- try {
- log.log(LogLevel.INFO, "Downloading keys for " + service);
- List<AthenzPublicKey> publicKeys = athenzClientFactory.createZmsClientWithServicePrincipal()
- .getPublicKeys(service);
- for (AthenzPublicKey publicKey : publicKeys) {
- FullKeyId fullKeyId = new FullKeyId(service, publicKey.getKeyId());
- log.log(LogLevel.DEBUG, "Adding key " + fullKeyId + " to the cache");
- cachedKeys.put(fullKeyId, publicKey.getPublicKey());
- }
- log.log(LogLevel.INFO, "Successfully downloaded keys for " + service);
- } catch (ZmsException e) {
- log.log(LogLevel.WARNING, "Failed to download keys for " + service + ": " + e.getMessage());
- }
- }
-
- private Optional<PublicKey> downloadPublicKey(FullKeyId fullKeyId) {
- try {
- log.log(LogLevel.INFO, "Downloading key " + fullKeyId);
- AthenzPublicKey publicKey = athenzClientFactory.createZmsClientWithServicePrincipal()
- .getPublicKey(fullKeyId.service, fullKeyId.keyId);
- return Optional.of(publicKey.getPublicKey());
- } catch (ZmsException e) {
- if (e.getCode() == 404) { // Key does not exist
- log.log(LogLevel.INFO, "Key " + fullKeyId + " not found");
- return Optional.empty();
- }
- String msg = String.format("Unable to retrieve public key from Athens (%s): %s", fullKeyId, e.getMessage());
- throw createException(msg, e);
- }
- }
-
- private static RuntimeException createException(String message, Exception cause) {
- log.log(LogLevel.ERROR, message);
- return new RuntimeException(message, cause);
- }
-
- private static class FullKeyId {
- private final AthenzService service;
- private final String keyId;
-
- private FullKeyId(AthenzService service, String keyId) {
- this.service = service;
- this.keyId = keyId;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- FullKeyId fullKeyId1 = (FullKeyId) o;
- return Objects.equals(service, fullKeyId1.service) &&
- Objects.equals(keyId, fullKeyId1.keyId);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(service, keyId);
- }
-
- @Override
- public String toString() {
- return "FullKeyId{" +
- "service=" + service +
- ", keyId='" + keyId + '\'' +
- '}';
- }
- }
-}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java
index 3ee2655108a..5e8674ce637 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java
@@ -5,8 +5,6 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId;
import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.hosted.controller.api.integration.athenz.ApplicationAction;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
-import com.yahoo.vespa.athenz.api.AthenzPublicKey;
-import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsClient;
import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsException;
@@ -96,16 +94,6 @@ public class ZmsClientMock implements ZmsClient {
return new ArrayList<>(athenz.domains.keySet());
}
- @Override
- public AthenzPublicKey getPublicKey(AthenzService service, String keyId) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public List<AthenzPublicKey> getPublicKeys(AthenzService service) {
- throw new UnsupportedOperationException();
- }
-
private AthenzDbMock.Domain getDomainOrThrow(AthenzDomain domainName, boolean verifyVespaTenant) {
AthenzDbMock.Domain domain = Optional.ofNullable(athenz.domains.get(domainName))
.orElseThrow(() -> zmsException(400, "Domain '%s' not found", domainName));
diff --git a/controller-server/src/main/resources/configdefinitions/athenz.def b/controller-server/src/main/resources/configdefinitions/athenz.def
index f8d65c25e47..172d5851dde 100644
--- a/controller-server/src/main/resources/configdefinitions/athenz.def
+++ b/controller-server/src/main/resources/configdefinitions/athenz.def
@@ -42,3 +42,6 @@ service.privateKeySecretName string
# Expiry of service principal token and certificate
service.credentialsExpiryMinutes int default=43200 # 30 days
+
+# Path to athenz.conf file
+athenzConfFile string \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java
index 301fc461b6f..9fe582b829f 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java
@@ -14,7 +14,7 @@ import com.yahoo.vespa.athenz.api.NToken;
import com.yahoo.vespa.athenz.tls.KeyAlgorithm;
import com.yahoo.vespa.athenz.tls.KeyUtils;
import com.yahoo.vespa.athenz.tls.X509CertificateBuilder;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.InvalidTokenException;
+import com.yahoo.vespa.athenz.utils.ntoken.NTokenValidator;
import com.yahoo.vespa.hosted.controller.restapi.ApplicationRequestToDiscFilterRequestWrapper;
import org.junit.Before;
import org.junit.Test;
@@ -71,7 +71,7 @@ public class AthenzPrincipalFilterTest {
AthenzPrincipal principal = new AthenzPrincipal(IDENTITY, NTOKEN);
validator.add(NTOKEN, principal);
- AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
DiscFilterRequest filterRequest = new ApplicationRequestToDiscFilterRequestWrapper(request);
filter.filter(filterRequest, new ResponseHandlerMock());
@@ -80,7 +80,7 @@ public class AthenzPrincipalFilterTest {
@Test
public void missing_token_and_certificate_is_unauthorized() {
- AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
DiscFilterRequest filterRequest = new ApplicationRequestToDiscFilterRequestWrapper(new Request("/"));
filter.filter(filterRequest, responseHandler);
@@ -91,7 +91,7 @@ public class AthenzPrincipalFilterTest {
public void invalid_token_is_unauthorized() {
Request request = defaultRequest();
- AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
DiscFilterRequest filterRequest = new ApplicationRequestToDiscFilterRequestWrapper(request);
filter.filter(filterRequest, responseHandler);
@@ -101,7 +101,7 @@ public class AthenzPrincipalFilterTest {
@Test
public void certificate_is_accepted() {
- AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
DiscFilterRequest filterRequest = new ApplicationRequestToDiscFilterRequestWrapper(new Request("/"), singletonList(CERTIFICATE));
filter.filter(filterRequest, responseHandler);
@@ -116,7 +116,7 @@ public class AthenzPrincipalFilterTest {
AthenzPrincipal principalWithToken = new AthenzPrincipal(IDENTITY, NTOKEN);
validator.add(NTOKEN, principalWithToken);
- AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
DiscFilterRequest filterRequest = new ApplicationRequestToDiscFilterRequestWrapper(request, singletonList(CERTIFICATE));
filter.filter(filterRequest, responseHandler);
@@ -130,7 +130,7 @@ public class AthenzPrincipalFilterTest {
AthenzUser conflictingIdentity = AthenzUser.fromUserId("mallory");
DiscFilterRequest filterRequest = new ApplicationRequestToDiscFilterRequestWrapper(request, singletonList(createSelfSignedCertificate(conflictingIdentity)));
- AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, ATHENZ_PRINCIPAL_HEADER, CORS_ALLOWED_URLS);
filter.filter(filterRequest, responseHandler);
assertUnauthorized(responseHandler, "Identity in principal token does not match x509 CN");
@@ -176,7 +176,7 @@ public class AthenzPrincipalFilterTest {
private final Map<NToken, AthenzPrincipal> validTokens = new HashMap<>();
NTokenValidatorMock() {
- super((service, keyId) -> Optional.empty());
+ super(keyId -> Optional.empty());
}
public NTokenValidatorMock add(NToken token, AthenzPrincipal principal) {
@@ -185,7 +185,7 @@ public class AthenzPrincipalFilterTest {
}
@Override
- AthenzPrincipal validate(NToken token) throws InvalidTokenException {
+ public AthenzPrincipal validate(NToken token) throws InvalidTokenException {
if (!validTokens.containsKey(token)) {
throw new InvalidTokenException("Invalid token");
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzTestUtils.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzTestUtils.java
deleted file mode 100644
index 40b38254dda..00000000000
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzTestUtils.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.athenz.filter;
-
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * @author bjorncs
- */
-public class AthenzTestUtils {
- public static KeyPair generateRsaKeypair() {
- try {
- KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
- keyGen.initialize(512);
- return keyGen.genKeyPair();
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java
deleted file mode 100644
index 510c806383c..00000000000
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.athenz.filter;
-
-import com.yahoo.athenz.auth.token.PrincipalToken;
-import com.yahoo.vespa.athenz.api.AthenzIdentity;
-import com.yahoo.vespa.athenz.api.AthenzPrincipal;
-import com.yahoo.vespa.athenz.api.AthenzUser;
-import com.yahoo.vespa.athenz.api.NToken;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.InvalidTokenException;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsKeystore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.time.Instant;
-import java.util.Optional;
-
-import static com.yahoo.vespa.athenz.utils.AthenzIdentities.ZMS_ATHENZ_SERVICE;
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author bjorncs
- */
-public class NTokenValidatorTest {
-
- private static final KeyPair TRUSTED_KEY = AthenzTestUtils.generateRsaKeypair();
- private static final KeyPair UNKNOWN_KEY = AthenzTestUtils.generateRsaKeypair();
- private static final AthenzIdentity IDENTITY = AthenzUser.fromUserId("myuser");
-
- @Rule
- public ExpectedException exceptionRule = ExpectedException.none();
-
- @Test
- public void valid_token_is_accepted() throws InvalidTokenException {
- NTokenValidator validator = new NTokenValidator(createKeystore());
- NToken token = createNToken(IDENTITY, Instant.now(), TRUSTED_KEY.getPrivate(), "0");
- AthenzPrincipal principal = validator.validate(token);
- assertEquals("user.myuser", principal.getIdentity().getFullName());
- }
-
- @Test
- public void invalid_signature_is_not_accepted() throws InvalidTokenException {
- NTokenValidator validator = new NTokenValidator(createKeystore());
- NToken token = createNToken(IDENTITY, Instant.now(), UNKNOWN_KEY.getPrivate(), "0");
- exceptionRule.expect(InvalidTokenException.class);
- exceptionRule.expectMessage("NToken is expired or has invalid signature");
- validator.validate(token);
- }
-
- @Test
- public void expired_token_is_not_accepted() throws InvalidTokenException {
- NTokenValidator validator = new NTokenValidator(createKeystore());
- NToken token = createNToken(IDENTITY, Instant.ofEpochMilli(1234) /*long time ago*/, TRUSTED_KEY.getPrivate(), "0");
- exceptionRule.expect(InvalidTokenException.class);
- exceptionRule.expectMessage("NToken is expired or has invalid signature");
- validator.validate(token);
- }
-
- @Test
- public void unknown_keyId_is_not_accepted() throws InvalidTokenException {
- NTokenValidator validator = new NTokenValidator(createKeystore());
- NToken token = createNToken(IDENTITY, Instant.now(), TRUSTED_KEY.getPrivate(), "unknown-key-id");
- exceptionRule.expect(InvalidTokenException.class);
- exceptionRule.expectMessage("NToken has an unknown keyId");
- validator.validate(token);
- }
-
- @Test
- public void failing_to_find_key_should_throw_exception() throws InvalidTokenException {
- ZmsKeystore keystore = (athensService, keyId) -> { throw new RuntimeException(); };
- NTokenValidator validator = new NTokenValidator(keystore);
- NToken token = createNToken(IDENTITY, Instant.now(), TRUSTED_KEY.getPrivate(), "0");
- exceptionRule.expect(InvalidTokenException.class);
- exceptionRule.expectMessage("Failed to retrieve public key");
- validator.validate(token);
- }
-
- private static ZmsKeystore createKeystore() {
- return (athensService, keyId) ->
- athensService.equals(ZMS_ATHENZ_SERVICE) && keyId.equals("0")
- ? Optional.of(TRUSTED_KEY.getPublic())
- : Optional.empty();
- }
-
- private static NToken createNToken(AthenzIdentity identity, Instant issueTime, PrivateKey privateKey, String keyId) {
- PrincipalToken token = new PrincipalToken.Builder("U1", identity.getDomain().getName(), identity.getName())
- .keyId(keyId)
- .salt("1234")
- .host("host")
- .ip("1.2.3.4")
- .issueTime(issueTime.getEpochSecond())
- .expirationWindow(1000)
- .build();
- token.sign(privateKey);
- return new NToken(token.getSignedToken());
- }
-
-}