aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@oath.com>2018-04-25 11:42:16 +0200
committerBjørn Christian Seime <bjorncs@oath.com>2018-04-25 13:54:19 +0200
commit61d6f63fd1b00d9880dd40d2d76e8fdaa8a36e56 (patch)
tree4485708fc5af23eaf382b7baabc86e59ee1127a4 /node-repository
parente2d4b112ef1308ea1e03c22e91e8dae561071f81 (diff)
Add separate node authentication filter
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/pom.xml6
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/AuthenticationFilter.java48
2 files changed, 54 insertions, 0 deletions
diff --git a/node-repository/pom.xml b/node-repository/pom.xml
index 6741163c19c..853a2e436f3 100644
--- a/node-repository/pom.xml
+++ b/node-repository/pom.xml
@@ -83,6 +83,12 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>jdisc-security-filters</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
<!-- compile -->
<dependency>
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/AuthenticationFilter.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/AuthenticationFilter.java
new file mode 100644
index 00000000000..53666f9f25f
--- /dev/null
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/AuthenticationFilter.java
@@ -0,0 +1,48 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.provision.restapi.v2.filter;
+
+import com.google.inject.Inject;
+import com.yahoo.config.provision.Zone;
+import com.yahoo.jdisc.Response;
+import com.yahoo.jdisc.http.filter.DiscFilterRequest;
+import com.yahoo.jdisc.http.filter.security.base.JsonSecurityRequestFilterBase;
+import com.yahoo.log.LogLevel;
+import com.yahoo.vespa.hosted.provision.NodeRepository;
+
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+/**
+ * A filter that authenticates the remote host based on the subject and subject alternative names in client certificate.
+ * A {@link NodePrincipal} object is assigned to user principal field if authentication is successful.
+ *
+ * @author bjorncs
+ */
+public class AuthenticationFilter extends JsonSecurityRequestFilterBase {
+
+ private static final Logger log = Logger.getLogger(AuthenticationFilter.class.getName());
+
+ private final HostAuthenticator authenticator;
+
+ @Inject
+ public AuthenticationFilter(Zone zone, NodeRepository nodeRepository) {
+ this.authenticator = new HostAuthenticator(zone, nodeRepository);
+ }
+
+ @Override
+ protected Optional<ErrorResponse> filter(DiscFilterRequest request) {
+ List<X509Certificate> clientCertificateChain = request.getClientCertificateChain();
+ if (clientCertificateChain.isEmpty())
+ return Optional.of(new ErrorResponse(Response.Status.UNAUTHORIZED, 0, "Missing client certificate"));
+ try {
+ NodePrincipal identity = authenticator.authenticate(clientCertificateChain);
+ request.setUserPrincipal(identity);
+ return Optional.empty();
+ } catch (HostAuthenticator.AuthenticationException e) {
+ log.log(LogLevel.WARNING, "Authentication failed: " + e.getMessage(), e);
+ return Optional.of(new ErrorResponse(Response.Status.UNAUTHORIZED, 1, e.getMessage()));
+ }
+ }
+}