diff options
author | Morten Tokle <mortent@verizonmedia.com> | 2020-02-03 09:40:42 +0100 |
---|---|---|
committer | Morten Tokle <mortent@verizonmedia.com> | 2020-02-03 13:26:35 +0100 |
commit | 57496f95277de1527876eac773e88f18edaac005 (patch) | |
tree | c94e9b0b9ee46fd86d7695ead7df51a3a9349e76 /vespa-athenz | |
parent | 802a97b6726b70acc68c0971b5bf6061f8e04539 (diff) |
Implement zts client getAccessToken
Diffstat (limited to 'vespa-athenz')
3 files changed, 97 insertions, 0 deletions
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java index eec578ddc26..c05213c8008 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java @@ -2,14 +2,17 @@ package com.yahoo.vespa.athenz.client.zts; import com.yahoo.security.Pkcs10Csr; +import com.yahoo.vespa.athenz.api.AthenzAccessToken; import com.yahoo.vespa.athenz.api.AthenzDomain; import com.yahoo.vespa.athenz.api.AthenzIdentity; +import com.yahoo.vespa.athenz.api.AthenzResourceName; import com.yahoo.vespa.athenz.api.AthenzRole; import com.yahoo.vespa.athenz.api.AwsRole; import com.yahoo.vespa.athenz.api.AwsTemporaryCredentials; import com.yahoo.vespa.athenz.api.NToken; import com.yahoo.vespa.athenz.api.ZToken; import com.yahoo.vespa.athenz.client.common.ClientBase; +import com.yahoo.vespa.athenz.client.zts.bindings.AccessTokenResponseEntity; import com.yahoo.vespa.athenz.client.zts.bindings.AwsTemporaryCredentialsResponseEntity; import com.yahoo.vespa.athenz.client.zts.bindings.IdentityRefreshRequestEntity; import com.yahoo.vespa.athenz.client.zts.bindings.IdentityResponseEntity; @@ -36,6 +39,7 @@ import java.time.Duration; import java.util.List; import java.util.Optional; import java.util.function.Supplier; +import java.util.stream.Collectors; import static java.util.stream.Collectors.toList; @@ -147,6 +151,33 @@ public class DefaultZtsClient extends ClientBase implements ZtsClient { } @Override + public AthenzAccessToken getAccessToken(AthenzDomain domain) { + return this.getAccessTokenImpl(List.of(new AthenzResourceName(domain, "domain"))); + } + + @Override + public AthenzAccessToken getAccessToken(List<AthenzRole> athenzRole) { + List<AthenzResourceName> athenzResourceNames = athenzRole.stream() + .map(AthenzRole::toResourceName) + .collect(toList()); + return this.getAccessTokenImpl(athenzResourceNames); + } + + private AthenzAccessToken getAccessTokenImpl(List<AthenzResourceName> resources) { + URI uri = ztsUrl.resolve("oauth2/token"); + RequestBuilder requestBuilder = RequestBuilder.post(uri) + .addHeader("Content-Type", "application/x-www-form-urlencoded") + .addParameter("grant_type", "client_credentials") + .addParameter("scope", resources.stream().map(AthenzResourceName::toResourceNameString).collect(Collectors.joining(" "))); + + HttpUriRequest request = requestBuilder.build(); + return execute(request, response -> { + AccessTokenResponseEntity accessTokenResponseEntity = readEntity(response, AccessTokenResponseEntity.class); + return accessTokenResponseEntity.accessToken(); + }); + } + + @Override public X509Certificate getRoleCertificate(AthenzRole role, Pkcs10Csr csr, Duration expiry) { RoleCertificateRequestEntity requestEntity = new RoleCertificateRequestEntity(csr, expiry); URI uri = ztsUrl.resolve(String.format("domain/%s/role/%s/token", role.domain().getName(), role.roleName())); diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java index c09ad8f48a0..baeb4271905 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.athenz.client.zts; import com.yahoo.security.Pkcs10Csr; +import com.yahoo.vespa.athenz.api.AthenzAccessToken; import com.yahoo.vespa.athenz.api.AthenzDomain; import com.yahoo.vespa.athenz.api.AthenzIdentity; import com.yahoo.vespa.athenz.api.AthenzRole; @@ -78,6 +79,22 @@ public interface ZtsClient extends AutoCloseable { ZToken getRoleToken(AthenzRole athenzRole); /** + * Fetch an access token for the target domain + * + * @param domain Target domain + * @return An Athenz access token + */ + AthenzAccessToken getAccessToken(AthenzDomain domain); + + /** + * Fetch an access token for the target roles + * + * @param athenzRole List of athenz roles to get access token for + * @return An Athenz access token + */ + AthenzAccessToken getAccessToken(List<AthenzRole> athenzRole); + + /** * Fetch role certificate for the target domain and role * * @param role Target role diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/AccessTokenResponseEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/AccessTokenResponseEntity.java new file mode 100644 index 00000000000..edd423b52bd --- /dev/null +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/AccessTokenResponseEntity.java @@ -0,0 +1,49 @@ +// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.athenz.client.zts.bindings; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.yahoo.vespa.athenz.api.AthenzAccessToken; +import com.yahoo.vespa.athenz.api.AthenzResourceName; +import com.yahoo.vespa.athenz.api.AthenzRole; + +import java.time.Instant; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author mortent + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class AccessTokenResponseEntity { + private final AthenzAccessToken accessToken; + private final Instant expiryTime; + private final List<AthenzRole> roles; + + public AccessTokenResponseEntity( + @JsonProperty("access_token") String accessToken, + @JsonProperty("expires_in") int expiresIn, + @JsonProperty("scope") String roles) { + + this.accessToken = new AthenzAccessToken(accessToken); + // We do not know from when, so best we can do is assume now ... + this.expiryTime = Instant.now().plusSeconds(expiresIn); + this.roles = Stream.of(roles.split(" ")) + .map(AthenzResourceName::fromString) + .map(AthenzRole::fromResourceName) + .collect(Collectors.toList()); + } + + public AthenzAccessToken accessToken() { + return accessToken; + } + + public Instant expiryTime() { + return expiryTime; + } + + public List<AthenzRole> roles() { + return roles; + } +} |