From 5d138a105e45c88490638f1f2de17df5591b5589 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 18 Feb 2025 15:33:27 +0100 Subject: [PATCH] Remove deprecated code. Removal of AppId, GcpIam authentication and deprecated methods. Closes #904 --- .../authentication/AppIdAuthentication.java | 122 -------- .../AppIdAuthenticationOptions.java | 157 ---------- .../authentication/AppIdUserIdMechanism.java | 37 --- .../authentication/GcpIamAuthentication.java | 169 ----------- .../GcpIamAuthenticationOptions.java | 287 ------------------ .../vault/authentication/IpAddressUserId.java | 41 --- .../LifecycleAwareSessionManagerSupport.java | 14 - .../authentication/MacAddressUserId.java | 177 ----------- .../vault/authentication/StaticUserId.java | 46 --- .../config/EnvironmentVaultConfiguration.java | 41 +-- .../mapping/VaultMappingContext.java | 14 - .../springframework/vault/support/Policy.java | 8 - .../vault/support/VaultSignRequest.java | 24 -- .../VaultSignatureVerificationRequest.java | 24 -- ...ppIdAuthenticationIntegrationTestBase.java | 59 ---- .../AppIdAuthenticationIntegrationTests.java | 66 ---- ...uthenticationOperatorIntegrationTests.java | 69 ----- ...IdAuthenticationStepsIntegrationTests.java | 70 ----- .../AppIdAuthenticationUnitTests.java | 90 ------ ...AuthenticationOptionsBuilderUnitTests.java | 128 -------- .../GcpIamAuthenticationUnitTests.java | 135 -------- .../authentication/IpAddressUserIdTests.java | 39 --- .../MacAddressUserIdUnitTests.java | 75 ----- ...igurationAppIdAuthenticationUnitTests.java | 58 ---- src/main/antora/modules/ROOT/nav.adoc | 2 - .../ROOT/pages/introduction/new-features.adoc | 76 ----- .../ROOT/pages/vault/authentication.adoc | 119 +------- .../ROOT/pages/vault/imperative-template.adoc | 9 +- 28 files changed, 4 insertions(+), 2152 deletions(-) delete mode 100644 spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthentication.java delete mode 100644 spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthenticationOptions.java delete mode 100644 spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdUserIdMechanism.java delete mode 100644 spring-vault-core/src/main/java/org/springframework/vault/authentication/GcpIamAuthentication.java delete mode 100644 spring-vault-core/src/main/java/org/springframework/vault/authentication/GcpIamAuthenticationOptions.java delete mode 100644 spring-vault-core/src/main/java/org/springframework/vault/authentication/IpAddressUserId.java delete mode 100644 spring-vault-core/src/main/java/org/springframework/vault/authentication/MacAddressUserId.java delete mode 100644 spring-vault-core/src/main/java/org/springframework/vault/authentication/StaticUserId.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationIntegrationTestBase.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationIntegrationTests.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationOperatorIntegrationTests.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationStepsIntegrationTests.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationUnitTests.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/GcpIamAuthenticationOptionsBuilderUnitTests.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/GcpIamAuthenticationUnitTests.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/IpAddressUserIdTests.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/authentication/MacAddressUserIdUnitTests.java delete mode 100644 spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppIdAuthenticationUnitTests.java delete mode 100644 src/main/antora/modules/ROOT/pages/introduction/new-features.adoc diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthentication.java deleted file mode 100644 index 2377e36b..00000000 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthentication.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.Assert; -import org.springframework.vault.support.VaultResponse; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestOperations; - -/** - * AppId implementation of {@link ClientAuthentication}. {@link AppIdAuthentication} uses - * a configured {@link AppIdUserIdMechanism} to obtain or calculate a UserId. AppId and - * UserId are sent in the login request to Vault to obtain a {@link VaultToken}. - * - * @author Mark Paluch - * @see AppIdAuthenticationOptions - * @see RestOperations - * @see Auth Backend: App - * ID - * @deprecated since 2.2. Use {@link AppRoleAuthentication}. - */ -@Deprecated(since = "2.2", forRemoval = true) -public class AppIdAuthentication implements ClientAuthentication, AuthenticationStepsFactory { - - private static final Log logger = LogFactory.getLog(AppIdAuthentication.class); - - private final AppIdAuthenticationOptions options; - - private final RestOperations restOperations; - - /** - * Create a {@link AppIdAuthentication} using {@link AppIdAuthenticationOptions} and - * {@link RestOperations}. - * @param options must not be {@literal null}. - * @param restOperations must not be {@literal null}. - */ - public AppIdAuthentication(AppIdAuthenticationOptions options, RestOperations restOperations) { - - Assert.notNull(options, "AppIdAuthenticationOptions must not be null"); - Assert.notNull(restOperations, "RestOperations must not be null"); - - this.options = options; - this.restOperations = restOperations; - } - - /** - * Creates a {@link AuthenticationSteps} for AppId authentication given - * {@link AppIdAuthenticationOptions}. - * @param options must not be {@literal null}. - * @return {@link AuthenticationSteps} for AppId authentication. - * @since 2.0 - */ - public static AuthenticationSteps createAuthenticationSteps(AppIdAuthenticationOptions options) { - - Assert.notNull(options, "AppIdAuthenticationOptions must not be null"); - - return AuthenticationSteps - .fromSupplier(() -> getAppIdLogin(options.getAppId(), options.getUserIdMechanism().createUserId())) // - .login(AuthenticationUtil.getLoginPath(options.getPath())); - } - - @Override - public VaultToken login() { - return createTokenUsingAppId(); - } - - @Override - public AuthenticationSteps getAuthenticationSteps() { - return createAuthenticationSteps(this.options); - } - - private VaultToken createTokenUsingAppId() { - - Map login = getAppIdLogin(this.options.getAppId(), - this.options.getUserIdMechanism().createUserId()); - - try { - VaultResponse response = this.restOperations - .postForObject(AuthenticationUtil.getLoginPath(this.options.getPath()), login, VaultResponse.class); - - Assert.state(response != null && response.getAuth() != null, "Auth field must not be null"); - - logger.debug("Login successful using AppId authentication"); - - return LoginTokenUtil.from(response.getAuth()); - } - catch (RestClientException e) { - throw VaultLoginException.create("app-id", e); - } - } - - private static Map getAppIdLogin(String appId, String userId) { - - Map login = new HashMap<>(); - - login.put("app_id", appId); - login.put("user_id", userId); - - return login; - } - -} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthenticationOptions.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthenticationOptions.java deleted file mode 100644 index 6bc49d34..00000000 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthenticationOptions.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import org.springframework.util.Assert; - -/** - * Authentication options for {@link AppIdAuthentication}. - *

- * Authentication options provide the path, appId and a {@link AppIdUserIdMechanism}. - * {@link AppIdAuthentication} can be constructed using {@link #builder()}. Instances of - * this class are immutable once constructed. - * - * @author Mark Paluch - * @see AppIdAuthentication - * @see AppIdUserIdMechanism - * @see #builder() - * @deprecated since 2.2. Use {@link AppRoleAuthentication}. - */ -@Deprecated(since = "2.2", forRemoval = true) -public class AppIdAuthenticationOptions { - - public static final String DEFAULT_APPID_AUTHENTICATION_PATH = "app-id"; - - /** - * Path of the appid authentication backend mount. - */ - private final String path; - - /** - * The AppId - */ - private final String appId; - - /** - * {@link AppIdUserIdMechanism} instance to obtain a userId. - */ - private final AppIdUserIdMechanism userIdMechanism; - - private AppIdAuthenticationOptions(String path, String appId, AppIdUserIdMechanism userIdMechanism) { - - this.path = path; - this.appId = appId; - this.userIdMechanism = userIdMechanism; - } - - /** - * @return a new {@link AppIdAuthenticationOptionsBuilder}. - */ - public static AppIdAuthenticationOptionsBuilder builder() { - return new AppIdAuthenticationOptionsBuilder(); - } - - /** - * @return the mount path. - */ - public String getPath() { - return this.path; - } - - /** - * @return the AppId. - */ - public String getAppId() { - return this.appId; - } - - /** - * @return the {@link AppIdUserIdMechanism}. - */ - public AppIdUserIdMechanism getUserIdMechanism() { - return this.userIdMechanism; - } - - /** - * Builder for {@link AppIdAuthenticationOptions}. - */ - public static class AppIdAuthenticationOptionsBuilder { - - private String path = DEFAULT_APPID_AUTHENTICATION_PATH; - - private String appId; - - private AppIdUserIdMechanism userIdMechanism; - - AppIdAuthenticationOptionsBuilder() { - } - - /** - * Configure the mount path. - * @param path must not be empty or {@literal null}. - * @return {@code this} {@link AppIdAuthenticationOptionsBuilder}. - * @see #DEFAULT_APPID_AUTHENTICATION_PATH - */ - public AppIdAuthenticationOptionsBuilder path(String path) { - - Assert.hasText(path, "Path must not be empty"); - - this.path = path; - return this; - } - - /** - * Configure the AppId. - * @param appId must not be empty or {@literal null}. - * @return {@code this} {@link AppIdAuthenticationOptionsBuilder}. - */ - public AppIdAuthenticationOptionsBuilder appId(String appId) { - - Assert.hasText(appId, "AppId must not be empty"); - - this.appId = appId; - return this; - } - - /** - * Configure the {@link AppIdUserIdMechanism}. - * @param userIdMechanism must not be {@literal null}. - * @return {@code this} {@link AppIdAuthenticationOptionsBuilder}. - */ - public AppIdAuthenticationOptionsBuilder userIdMechanism(AppIdUserIdMechanism userIdMechanism) { - - Assert.notNull(userIdMechanism, "AppIdUserIdMechanism must not be null"); - - this.userIdMechanism = userIdMechanism; - return this; - } - - /** - * Build a new {@link AppIdAuthenticationOptions} instance. Requires - * {@link #userIdMechanism(AppIdUserIdMechanism)} to be configured. - * @return a new {@link AppIdAuthenticationOptions}. - */ - public AppIdAuthenticationOptions build() { - - Assert.hasText(this.appId, "AppId must not be empty"); - Assert.notNull(this.userIdMechanism, "AppIdUserIdMechanism must not be null"); - - return new AppIdAuthenticationOptions(this.path, this.appId, this.userIdMechanism); - } - - } - -} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdUserIdMechanism.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdUserIdMechanism.java deleted file mode 100644 index 929af499..00000000 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdUserIdMechanism.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.vault.authentication; - -/** - * Interface to obtain a UserId for AppId authentication. Implementations are used by - * {@link AppIdAuthentication}. - * - * @author Mark Paluch - * @see AppIdAuthentication - * @deprecated since 2.2. Use {@link AppRoleAuthentication}. - */ -@Deprecated(since = "2.2", forRemoval = true) -@FunctionalInterface -public interface AppIdUserIdMechanism { - - /** - * Create a UserId for AppId authentication. - * @return the UserId. - */ - String createUserId(); - -} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/GcpIamAuthentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/GcpIamAuthentication.java deleted file mode 100644 index fdb3b3c4..00000000 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/GcpIamAuthentication.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2018-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.io.IOException; -import java.time.Instant; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.services.iam.v1.Iam; -import com.google.api.services.iam.v1.Iam.Builder; -import com.google.api.services.iam.v1.Iam.Projects.ServiceAccounts.SignJwt; -import com.google.api.services.iam.v1.model.SignJwtRequest; -import com.google.api.services.iam.v1.model.SignJwtResponse; -import com.google.auth.oauth2.GoogleCredentials; - -import org.springframework.util.Assert; -import org.springframework.vault.VaultException; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.client.RestOperations; - -/** - * GCP IAM login implementation using GCP IAM service accounts to legitimate its - * authenticity via JSON Web Token using the deprecated IAM - * {@code projects.serviceAccounts.signJwt} method. - *

- * This authentication method uses Googles IAM API to obtain a signed token for a specific - * {@link com.google.api.client.auth.oauth2.Credential}. Project and service account - * details are obtained from a {@link GoogleCredential} that can be retrieved either from - * a JSON file or the runtime environment (GAE, GCE). - *

- * {@link GcpIamAuthentication} uses Google Java API that uses synchronous API. - * - * @author Mark Paluch - * @author Magnus Jungsbluth - * @author Bruno Rodrigues - * @since 2.1 - * @see GcpIamAuthenticationOptions - * @see HttpTransport - * @see GoogleCredential - * @see GoogleCredentials#getApplicationDefault() - * @see RestOperations - * @see Auth Backend: gcp - * (IAM) - * @see GCP: - * projects.serviceAccounts.signJwt - * @deprecated since 2.3.2, use {@link GcpIamCredentialsAuthentication} instead. - */ -@Deprecated(since = "2.3.2", forRemoval = true) -public class GcpIamAuthentication extends GcpJwtAuthenticationSupport implements ClientAuthentication { - - private static final String SCOPE = "https://www.googleapis.com/auth/iam"; - - private final GcpIamAuthenticationOptions options; - - private final HttpTransport httpTransport; - - private final GoogleCredential credential; - - /** - * Create a new instance of {@link GcpIamAuthentication} given - * {@link GcpIamAuthenticationOptions} and {@link RestOperations}. This constructor - * initializes {@link NetHttpTransport} for Google API usage. - * @param options must not be {@literal null}. - * @param restOperations HTTP client for Vault login, must not be {@literal null}. - */ - public GcpIamAuthentication(GcpIamAuthenticationOptions options, RestOperations restOperations) { - this(options, restOperations, new NetHttpTransport()); - } - - /** - * Create a new instance of {@link GcpIamAuthentication} given - * {@link GcpIamAuthenticationOptions}, {@link RestOperations} and - * {@link HttpTransport}. - * @param options must not be {@literal null}. - * @param restOperations HTTP client for Vault login, must not be {@literal null}. - * @param httpTransport HTTP client for Google API use, must not be {@literal null}. - */ - public GcpIamAuthentication(GcpIamAuthenticationOptions options, RestOperations restOperations, - HttpTransport httpTransport) { - - super(restOperations); - - Assert.notNull(options, "GcpIamAuthenticationOptions must not be null"); - Assert.notNull(restOperations, "RestOperations must not be null"); - Assert.notNull(httpTransport, "HttpTransport must not be null"); - - this.options = options; - this.httpTransport = httpTransport; - this.credential = options.getCredentialSupplier().get().createScoped(Collections.singletonList(SCOPE)); - } - - @Override - public VaultToken login() throws VaultException { - - String signedJwt = signJwt(); - - return doLogin("GCP-IAM", signedJwt, this.options.getPath(), this.options.getRole()); - } - - protected String signJwt() { - - String projectId = getProjectId(); - String serviceAccount = getServiceAccountId(); - Map jwtPayload = getJwtPayload(this.options, serviceAccount); - - Iam iam = new Builder(this.httpTransport, GoogleJsonUtil.JSON_FACTORY, this.credential) - .setApplicationName("Spring Vault/" + getClass().getName()) - .build(); - - try { - - String payload = GoogleJsonUtil.JSON_FACTORY.toString(jwtPayload); - SignJwtRequest request = new SignJwtRequest(); - request.setPayload(payload); - - SignJwt signJwt = iam.projects() - .serviceAccounts() - .signJwt("projects/%s/serviceAccounts/%s".formatted(projectId, serviceAccount), request); - - SignJwtResponse response = signJwt.execute(); - - return response.getSignedJwt(); - } - catch (IOException e) { - throw new VaultLoginException("Cannot sign JWT", e); - } - } - - private String getServiceAccountId() { - return this.options.getServiceAccountIdAccessor().getServiceAccountId(this.credential); - } - - private String getProjectId() { - return this.options.getProjectIdAccessor().getProjectId(this.credential); - } - - private static Map getJwtPayload(GcpIamAuthenticationOptions options, String serviceAccount) { - - Instant validUntil = options.getClock().instant().plus(options.getJwtValidity()); - - Map payload = new LinkedHashMap<>(); - - payload.put("sub", serviceAccount); - payload.put("aud", "vault/" + options.getRole()); - payload.put("exp", validUntil.getEpochSecond()); - - return payload; - } - -} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/GcpIamAuthenticationOptions.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/GcpIamAuthenticationOptions.java deleted file mode 100644 index 81e68906..00000000 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/GcpIamAuthenticationOptions.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2018-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.time.Clock; -import java.time.Duration; - -import com.google.api.client.auth.oauth2.Credential; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import org.jspecify.annotations.Nullable; - -import org.springframework.util.Assert; - -/** - * Authentication options for {@link GcpIamAuthentication}. - *

- * Authentication options provide the path, a {@link GcpCredentialSupplier}, role and JWT - * expiry for GCP IAM authentication. Instances of this class are immutable once - * constructed. - * - * @author Mark Paluch - * @author Magnus Jungsbluth - * @see GcpIamAuthentication - * @see #builder() - * @since 2.1 - * @deprecated since 2.3.2 - */ -@Deprecated(since = "2.3.2", forRemoval = true) -public class GcpIamAuthenticationOptions extends GcpIamAuthenticationSupport { - - public static final String DEFAULT_GCP_AUTHENTICATION_PATH = "gcp"; - - private final GcpCredentialSupplier credentialSupplier; - - /** - * Provide the service account id to use as sub/iss claims. - */ - private final GcpServiceAccountIdAccessor serviceAccountIdAccessor; - - /** - * The GCP project id to use in GCP IAM API calls. - */ - private final GcpProjectIdAccessor projectIdAccessor; - - private GcpIamAuthenticationOptions(String path, GcpCredentialSupplier credentialSupplier, String role, - Duration jwtValidity, Clock clock, GcpServiceAccountIdAccessor serviceAccountIdSupplier, - GcpProjectIdAccessor projectIdAccessor) { - - super(path, role, jwtValidity, clock); - - this.credentialSupplier = credentialSupplier; - this.serviceAccountIdAccessor = serviceAccountIdSupplier; - this.projectIdAccessor = projectIdAccessor; - } - - /** - * @return a new {@link GcpIamAuthenticationOptionsBuilder}. - */ - public static GcpIamAuthenticationOptionsBuilder builder() { - return new GcpIamAuthenticationOptionsBuilder(); - } - - /** - * @return the gcp {@link Credential} supplier. - */ - public GcpCredentialSupplier getCredentialSupplier() { - return this.credentialSupplier; - } - - /** - * @return the service account id to use as sub/iss claims. - * @since 2.1 - */ - public GcpServiceAccountIdAccessor getServiceAccountIdAccessor() { - return this.serviceAccountIdAccessor; - } - - /** - * @return GCP project id accessor to obtain the project id of GCP IAM API calls. - * @since 2.1 - */ - public GcpProjectIdAccessor getProjectIdAccessor() { - return this.projectIdAccessor; - } - - /** - * Builder for {@link GcpIamAuthenticationOptions}. - */ - public static class GcpIamAuthenticationOptionsBuilder { - - private String path = DEFAULT_GCP_AUTHENTICATION_PATH; - - @Nullable - private String role; - - @Nullable - private GcpCredentialSupplier credentialSupplier; - - private Duration jwtValidity = Duration.ofMinutes(15); - - private Clock clock = Clock.systemDefaultZone(); - - private GcpServiceAccountIdAccessor serviceAccountIdAccessor = DefaultGcpCredentialAccessors.INSTANCE; - - private GcpProjectIdAccessor projectIdAccessor = DefaultGcpCredentialAccessors.INSTANCE; - - GcpIamAuthenticationOptionsBuilder() { - } - - /** - * Configure the mount path, defaults to {@literal aws}. - * @param path must not be empty or {@literal null}. - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - */ - public GcpIamAuthenticationOptionsBuilder path(String path) { - - Assert.hasText(path, "Path must not be empty"); - - this.path = path; - return this; - } - - /** - * Configure static Google credentials, required to create a signed JWT. Either - * use static credentials or provide a - * {@link #credentialSupplier(GcpCredentialSupplier) credentials provider}. - * @param credential must not be {@literal null}. - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - * @see #credentialSupplier(GcpCredentialSupplier) - */ - public GcpIamAuthenticationOptionsBuilder credential(GoogleCredential credential) { - - Assert.notNull(credential, "Credential must not be null"); - - return credentialSupplier(() -> credential); - } - - /** - * Configure a {@link GcpCredentialSupplier}, required to create a signed JWT. - * Alternatively, configure static {@link #credential(GoogleCredential) - * credentials}. - * @param credentialSupplier must not be {@literal null}. - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - * @see #credential(GoogleCredential) - */ - public GcpIamAuthenticationOptionsBuilder credentialSupplier(GcpCredentialSupplier credentialSupplier) { - - Assert.notNull(credentialSupplier, "GcpCredentialSupplier must not be null"); - - this.credentialSupplier = credentialSupplier; - return this; - } - - /** - * Configure an explicit service account id to use in GCP IAM calls. If none is - * configured, falls back to using {@link GoogleCredential#getServiceAccountId()}. - * @param serviceAccountId the service account id (email) to use - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - * @since 2.1 - */ - public GcpIamAuthenticationOptionsBuilder serviceAccountId(String serviceAccountId) { - - Assert.notNull(serviceAccountId, "Service account id may not be null"); - - return serviceAccountIdAccessor((GoogleCredential credential) -> serviceAccountId); - } - - /** - * Configure an {@link GcpServiceAccountIdAccessor} to obtain the service account - * id used in GCP IAM calls. If none is configured, falls back to using - * {@link GoogleCredential#getServiceAccountId()}. - * @param serviceAccountIdAccessor the service account id provider to use - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - * @see GcpServiceAccountIdAccessor - * @since 2.1 - */ - GcpIamAuthenticationOptionsBuilder serviceAccountIdAccessor( - GcpServiceAccountIdAccessor serviceAccountIdAccessor) { - - Assert.notNull(serviceAccountIdAccessor, "GcpServiceAccountIdAccessor must not be null"); - - this.serviceAccountIdAccessor = serviceAccountIdAccessor; - return this; - } - - /** - * Configure an explicit GCP project id to use in GCP IAM API calls. If none is - * configured, falls back using - * {@link GoogleCredential#getServiceAccountProjectId()}. - * @param projectId the GCP project id to use in GCP IAM API calls - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - * @since 2.1 - */ - public GcpIamAuthenticationOptionsBuilder projectId(String projectId) { - - Assert.notNull(projectId, "GCP project id must not be null"); - - return projectIdAccessor((GoogleCredential credential) -> projectId); - } - - /** - * Configure an {@link GcpProjectIdAccessor} to use in GCP IAM API calls. If none - * is configured, falls back using - * {@link GoogleCredential#getServiceAccountProjectId()}. - * @param projectIdAccessor the GCP project id supplier to use in GCP IAM API - * calls - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - * @since 2.1 - */ - GcpIamAuthenticationOptionsBuilder projectIdAccessor(GcpProjectIdAccessor projectIdAccessor) { - - Assert.notNull(projectIdAccessor, "GcpProjectIdAccessor must not be null"); - - this.projectIdAccessor = projectIdAccessor; - return this; - } - - /** - * Configure the name of the role against which the login is being attempted. - * @param role must not be empty or {@literal null}. - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - */ - public GcpIamAuthenticationOptionsBuilder role(String role) { - - Assert.hasText(role, "Role must not be null or empty"); - - this.role = role; - return this; - } - - /** - * Configure the {@link Duration} for the JWT expiration. This defaults to 15 - * minutes and cannot be more than a hour. - * @param jwtValidity must not be {@literal null}. - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - */ - public GcpIamAuthenticationOptionsBuilder jwtValidity(Duration jwtValidity) { - - Assert.notNull(jwtValidity, "JWT validity duration must not be null"); - - this.jwtValidity = jwtValidity; - return this; - } - - /** - * Configure the {@link Clock} used to calculate epoch seconds until the JWT - * expiration. - * @param clock must not be {@literal null}. - * @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}. - */ - public GcpIamAuthenticationOptionsBuilder clock(Clock clock) { - - Assert.notNull(clock, "Clock must not be null"); - - this.clock = clock; - return this; - } - - /** - * Build a new {@link GcpIamAuthenticationOptions} instance. - * @return a new {@link GcpIamAuthenticationOptions}. - */ - public GcpIamAuthenticationOptions build() { - - Assert.notNull(this.credentialSupplier, "GcpCredentialSupplier must not be null"); - Assert.notNull(this.role, "Role must not be null"); - - return new GcpIamAuthenticationOptions(this.path, this.credentialSupplier, this.role, this.jwtValidity, - this.clock, this.serviceAccountIdAccessor, this.projectIdAccessor); - } - - } - -} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/IpAddressUserId.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/IpAddressUserId.java deleted file mode 100644 index 95e53871..00000000 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/IpAddressUserId.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.vault.authentication; - -import java.io.IOException; -import java.net.InetAddress; - -/** - * Mechanism to generate a SHA-256 hashed and hex-encoded representation of the IP - * address. Can be calculated with {@code echo -n 192.168.99.1 | sha256sum}. - * - * @author Mark Paluch - * @see AppIdUserIdMechanism - */ -public class IpAddressUserId implements AppIdUserIdMechanism { - - @Override - public String createUserId() { - try { - return Sha256.toSha256(InetAddress.getLocalHost().getHostAddress()); - } - catch (IOException e) { - throw new IllegalStateException(e); - } - } - -} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupport.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupport.java index 38996086..687d27dd 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupport.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManagerSupport.java @@ -204,20 +204,6 @@ public abstract class LifecycleAwareSessionManagerSupport extends Authentication */ public interface RefreshTrigger { - /** - * Determine the next execution time according to the given trigger context. - * @param loginToken login token encapsulating renewability and lease duration. - * @return the next execution time as defined by the trigger, or {@code null} if - * the trigger won't fire anymore. - * @deprecated since 3.1, use {@link #nextExecution(LoginToken) instead}. - */ - @Nullable - @Deprecated(since = "3.1") - default Date nextExecutionTime(LoginToken loginToken) { - Instant instant = nextExecution(loginToken); - return instant != null ? Date.from(instant) : null; - } - /** * Determine the next execution time according to the given trigger context. * @param loginToken login token encapsulating renewability and lease duration. diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/MacAddressUserId.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/MacAddressUserId.java deleted file mode 100644 index 6f32c708..00000000 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/MacAddressUserId.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Mechanism to generate a UserId based on the Mac address. {@link MacAddressUserId} - * creates a hex-encoded representation of the Mac address without any separators - * (0123456789AB). A network interface hint can be specified optionally to select a - * network interface (index/name). - * - * @author Mark Paluch - * @see AppIdUserIdMechanism - */ -public class MacAddressUserId implements AppIdUserIdMechanism { - - private final Log logger = LogFactory.getLog(MacAddressUserId.class); - - private final String networkInterfaceHint; - - /** - * Create a new {@link MacAddressUserId} using the {@link NetworkInterface} from the - * {@link InetAddress#getLocalHost()}. - */ - public MacAddressUserId() { - this(""); - } - - /** - * Create a new {@link MacAddressUserId} using a {@code networkInterfaceIndex}. The - * index is applied to {@link NetworkInterface#getNetworkInterfaces()} to obtain the - * desired network interface. - * @param networkInterfaceIndex must be greater or equal to zero. - */ - public MacAddressUserId(int networkInterfaceIndex) { - - Assert.isTrue(networkInterfaceIndex >= 0, "NetworkInterfaceIndex must be greater or equal to 0"); - - this.networkInterfaceHint = "" + networkInterfaceIndex; - } - - /** - * Create a new {@link MacAddressUserId} using a {@code networkInterfaceName}. This - * name is compared with {@link NetworkInterface#getName()} and - * {@link NetworkInterface#getDisplayName()} to obtain the desired network interface. - * @param networkInterfaceName must not be {@literal null}. - */ - public MacAddressUserId(String networkInterfaceName) { - - Assert.notNull(networkInterfaceName, "NetworkInterfaceName must not be null"); - - this.networkInterfaceHint = networkInterfaceName; - } - - @Override - public String createUserId() { - - try { - - Optional networkInterface = Optional.empty(); - List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); - - if (StringUtils.hasText(this.networkInterfaceHint)) { - - try { - networkInterface = getNetworkInterface(Integer.parseInt(this.networkInterfaceHint), interfaces); - } - catch (NumberFormatException e) { - networkInterface = getNetworkInterface((this.networkInterfaceHint), interfaces); - } - } - - if (!networkInterface.isPresent()) { - - if (StringUtils.hasText(this.networkInterfaceHint)) { - this.logger - .warn("Did not find a NetworkInterface applying hint %s".formatted(this.networkInterfaceHint)); - } - - InetAddress localHost = InetAddress.getLocalHost(); - networkInterface = Optional.ofNullable(NetworkInterface.getByInetAddress(localHost)); - - if (!networkInterface.filter(MacAddressUserId::hasNetworkAddress).isPresent()) { - networkInterface = getNetworkInterfaceWithHardwareAddress(interfaces); - } - } - - return networkInterface.map(MacAddressUserId::getRequiredNetworkAddress) // - .map(Sha256::toHexString) // - .map(Sha256::toSha256) // - .orElseThrow(() -> new IllegalStateException("Cannot determine NetworkInterface")); - } - catch (IOException e) { - throw new IllegalStateException(e); - } - - } - - private static Optional getNetworkInterface(Number hint, List interfaces) { - - if (interfaces.size() > hint.intValue() && hint.intValue() >= 0) { - return Optional.of(interfaces.get(hint.intValue())); - } - - return Optional.empty(); - } - - private static Optional getNetworkInterface(String hint, List interfaces) { - - return interfaces.stream() // - .filter(anInterface -> matchesHint(hint, anInterface)) // - .findFirst(); - } - - private static boolean matchesHint(String hint, NetworkInterface networkInterface) { - - return hint.equals(networkInterface.getDisplayName()) || hint.equals(networkInterface.getName()); - } - - private static Optional getNetworkInterfaceWithHardwareAddress( - List interfaces) { - - return interfaces.stream() // - .filter(MacAddressUserId::hasNetworkAddress) // - .sorted(Comparator.comparingInt(NetworkInterface::getIndex)) // - .findFirst(); - } - - private static Optional getNetworkAddress(NetworkInterface it) { - - try { - return Optional.ofNullable(it.getHardwareAddress()); - } - catch (SocketException e) { - throw new IllegalStateException("Cannot determine hardware address for %s".formatted(it.getName())); - } - } - - private static byte[] getRequiredNetworkAddress(NetworkInterface it) { - - return getNetworkAddress(it) // - .orElseThrow(() -> new IllegalStateException( - "Network interface %s has no hardware address".formatted(it.getName()))); - } - - private static boolean hasNetworkAddress(NetworkInterface it) { - return getNetworkAddress(it).isPresent(); - } - -} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/StaticUserId.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/StaticUserId.java deleted file mode 100644 index 9cee4cec..00000000 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/StaticUserId.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.vault.authentication; - -import org.springframework.util.Assert; - -/** - * A static UserId. - * - * @author Mark Paluch - * @see AppIdUserIdMechanism - */ -public class StaticUserId implements AppIdUserIdMechanism { - - private final String userId; - - /** - * Create a new {@link StaticUserId} for a given {@code userId}. - * @param userId must not be empty or {@literal null}. - */ - public StaticUserId(String userId) { - - Assert.hasText(userId, "UserId must not be empty"); - this.userId = userId; - } - - @Override - public String createUserId() { - return this.userId; - } - -} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/config/EnvironmentVaultConfiguration.java b/spring-vault-core/src/main/java/org/springframework/vault/config/EnvironmentVaultConfiguration.java index 88972d57..a9908b24 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/config/EnvironmentVaultConfiguration.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/config/EnvironmentVaultConfiguration.java @@ -34,7 +34,6 @@ import org.springframework.core.io.Resource; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.vault.authentication.*; -import org.springframework.vault.authentication.AppIdAuthenticationOptions.AppIdAuthenticationOptionsBuilder; import org.springframework.vault.authentication.AppRoleAuthenticationOptions.AppRoleAuthenticationOptionsBuilder; import org.springframework.vault.authentication.AppRoleAuthenticationOptions.RoleId; import org.springframework.vault.authentication.AppRoleAuthenticationOptions.SecretId; @@ -263,7 +262,6 @@ public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration im return switch (authenticationMethod) { case TOKEN -> tokenAuthentication(); - case APPID -> appIdAuthentication(); case APPROLE -> appRoleAuthentication(); case AWS_EC2 -> awsEc2Authentication(); case AWS_IAM -> awsIamAuthentication(); @@ -288,24 +286,6 @@ public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration im return new TokenAuthentication(token); } - protected ClientAuthentication appIdAuthentication() { - - String appId = getProperty("vault.app-id.app-id", getProperty("spring.application.name")); - String userId = getProperty("vault.app-id.user-id"); - String path = getProperty("vault.app-id.app-id-path", - AppIdAuthenticationOptions.DEFAULT_APPID_AUTHENTICATION_PATH); - - Assert.hasText(appId, "Vault AppId authentication: AppId (vault.app-id.app-id) must not be empty"); - Assert.hasText(userId, "Vault AppId authentication: UserId (vault.app-id.user-id) must not be empty"); - - AppIdAuthenticationOptionsBuilder builder = AppIdAuthenticationOptions.builder() - .appId(appId) - .userIdMechanism(getAppIdUserIdMechanism(userId)) - .path(path); - - return new AppIdAuthentication(builder.build(), restOperations()); - } - protected ClientAuthentication appRoleAuthentication() { String roleId = getProperty("vault.app-role.role-id"); @@ -326,19 +306,6 @@ public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration im return new AppRoleAuthentication(builder.build(), restOperations()); } - protected AppIdUserIdMechanism getAppIdUserIdMechanism(String userId) { - - if (userId.equalsIgnoreCase(AppIdUserId.IP_ADDRESS.name())) { - return new IpAddressUserId(); - } - - if (userId.equalsIgnoreCase(AppIdUserId.MAC_ADDRESS.name())) { - return new MacAddressUserId(); - } - - return new StaticUserId(userId); - } - protected ClientAuthentication awsEc2Authentication() { String role = getProperty("vault.aws-ec2.role"); @@ -463,15 +430,9 @@ public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration im return value != null ? this.applicationContext.getResource(value) : null; } - enum AppIdUserId { - - IP_ADDRESS, MAC_ADDRESS; - - } - enum AuthenticationMethod { - TOKEN, APPID, APPROLE, AWS_EC2, AWS_IAM, AZURE, CERT, CUBBYHOLE, KUBERNETES; + TOKEN, APPROLE, AWS_EC2, AWS_IAM, AZURE, CERT, CUBBYHOLE, KUBERNETES; } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/repository/mapping/VaultMappingContext.java b/spring-vault-core/src/main/java/org/springframework/vault/repository/mapping/VaultMappingContext.java index eddbc376..b64ecc66 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/repository/mapping/VaultMappingContext.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/repository/mapping/VaultMappingContext.java @@ -15,9 +15,6 @@ */ package org.springframework.vault.repository.mapping; -import org.jspecify.annotations.Nullable; - -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; @@ -31,17 +28,6 @@ import org.springframework.data.util.TypeInformation; */ public class VaultMappingContext extends KeyValueMappingContext, VaultPersistentProperty> { - /** - * @return the {@link KeySpaceResolver} if configured. - * @deprecated since 3.1, {@link KeySpaceResolver} has fully moved into - * {@link KeyValueMappingContext}. - */ - @Nullable - @Deprecated(since = "3.1", forRemoval = true) - public KeySpaceResolver getFallbackKeySpaceResolver() { - return super.getKeySpaceResolver(); - } - @Override protected VaultPersistentEntity createPersistentEntity(TypeInformation typeInformation) { return new BasicVaultPersistentEntity<>(typeInformation, getKeySpaceResolver()); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/Policy.java b/spring-vault-core/src/main/java/org/springframework/vault/support/Policy.java index 5f39591c..ef55b2ef 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/Policy.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/Policy.java @@ -546,14 +546,6 @@ public class Policy { */ UPDATE, - /** - * Deprecated: Previous capability literal before it was split into - * {@link #CREATE} and {@link #UPDATE}. - * @deprecated since 2.3 and Vault 0.5. - */ - @Deprecated(since = "2.3") - WRITE, - /** * Allows deleting the data at the given path. */ diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultSignRequest.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultSignRequest.java index f638587e..bd77aa59 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultSignRequest.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultSignRequest.java @@ -90,17 +90,6 @@ public class VaultSignRequest { return this.signatureAlgorithm; } - /** - * @return algorithm used for creating the signature or {@literal null} to use the - * default algorithm. - * @deprecated since 2.4, use {@link #getSignatureAlgorithm()} instead. - */ - @Deprecated(since = "2.4") - @Nullable - public String getAlgorithm() { - return getSignatureAlgorithm(); - } - /** * @return true if the input is already hashed. * @since 3.1 @@ -180,19 +169,6 @@ public class VaultSignRequest { return this; } - /** - * Configure the algorithm to be used for the operation. - * @param algorithm Specify the algorithm to be used for the operation. Supported - * algorithms are: {@literal sha2-224}, {@literal sha2-256}, {@literal sha2-384}, - * {@literal sha2-512}. Defaults to {@literal sha2-256} if not set. - * @return {@code this} {@link VaultSignRequestBuilder}. - * @deprecated since 2.4, use {@link #signatureAlgorithm(String)} instead. - */ - @Deprecated(since = "2.4") - public VaultSignRequestBuilder algorithm(String algorithm) { - return signatureAlgorithm(algorithm); - } - /** * Build a new {@link VaultSignRequest} instance. Requires * {@link #plaintext(Plaintext)} to be configured. diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultSignatureVerificationRequest.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultSignatureVerificationRequest.java index a8b27bb4..26aed5b3 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultSignatureVerificationRequest.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultSignatureVerificationRequest.java @@ -130,17 +130,6 @@ public class VaultSignatureVerificationRequest { return this.signatureAlgorithm; } - /** - * @return algorithm used for verifying the signature or {@literal null} to use the - * default algorithm. - * @deprecated since 2.4, use {@link #getSignatureAlgorithm()} instead. - */ - @Nullable - @Deprecated(since = "2.4") - public String getAlgorithm() { - return getSignatureAlgorithm(); - } - /** * @return {@literal true} if the input is already hashed. * @since 3.1 @@ -258,19 +247,6 @@ public class VaultSignatureVerificationRequest { return this; } - /** - * Configure the algorithm to be used for the operation. - * @param algorithm Specify the algorithm to be used for the operation. Supported - * algorithms are: {@literal sha2-224}, {@literal sha2-256}, {@literal sha2-384}, - * {@literal sha2-512}. Defaults to {@literal sha2-256} if not set. - * @return {@code this} {@link VaultSignatureVerificationRequestBuilder}. - * @deprecated since 2.4, use {@link #signatureAlgorithm(String)} instead. - */ - @Deprecated(since = "2.4") - public VaultSignatureVerificationRequestBuilder algorithm(String algorithm) { - return signatureAlgorithm(algorithm); - } - /** * Build a new {@link VaultSignatureVerificationRequest} instance. Requires * {@link #plaintext(Plaintext)} and one of {@link #hmac(Hmac)}, diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationIntegrationTestBase.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationIntegrationTestBase.java deleted file mode 100644 index 888f58cf..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationIntegrationTestBase.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; - -import org.springframework.vault.util.DisabledOnVaultVersion; -import org.springframework.vault.util.IntegrationTestSupport; - -/** - * Integration test base class for {@link AppIdAuthentication} tests. - * - * @author Mark Paluch - */ -@DisabledOnVaultVersion("1.12") -public abstract class AppIdAuthenticationIntegrationTestBase extends IntegrationTestSupport { - - @BeforeEach - public void before() { - - if (!prepare().hasAuth("app-id")) { - prepare().mountAuth("app-id"); - } - - prepare().getVaultOperations().doWithSession(restOperations -> { - - Map appIdData = new HashMap(); - appIdData.put("value", "dummy"); // policy - appIdData.put("display_name", "this is my test application"); - - restOperations.postForEntity("auth/app-id/map/app-id/myapp", appIdData, Map.class); - - Map userIdData = new HashMap(); - userIdData.put("value", "myapp"); // name of the app-id - userIdData.put("cidr_block", "0.0.0.0/0"); - - restOperations.postForEntity("auth/app-id/map/user-id/static-userid-value", userIdData, Map.class); - - return null; - }); - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationIntegrationTests.java deleted file mode 100644 index eb1816c9..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationIntegrationTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import org.junit.jupiter.api.Test; - -import org.springframework.vault.VaultException; -import org.springframework.vault.support.VaultToken; -import org.springframework.vault.util.Settings; -import org.springframework.vault.util.TestRestTemplateFactory; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.*; - -/** - * Integration tests for {@link AppIdAuthentication}. - * - * @author Mark Paluch - */ -class AppIdAuthenticationIntegrationTests extends AppIdAuthenticationIntegrationTestBase { - - @Test - void shouldLoginSuccessfully() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("myapp") // - .userIdMechanism(new StaticUserId("static-userid-value")) // - .build(); - - RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration()); - - AppIdAuthentication authentication = new AppIdAuthentication(options, restTemplate); - VaultToken login = authentication.login(); - - assertThat(login.getToken()).isNotEmpty(); - } - - @Test - void loginShouldFail() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("wrong") // - .userIdMechanism(new StaticUserId("wrong")) // - .build(); - - RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration()); - - assertThatExceptionOfType(VaultException.class) - .isThrownBy(() -> new AppIdAuthentication(options, restTemplate).login()); - - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationOperatorIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationOperatorIntegrationTests.java deleted file mode 100644 index a0e4ef3d..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationOperatorIntegrationTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import org.junit.jupiter.api.Test; -import reactor.test.StepVerifier; - -import org.springframework.vault.util.Settings; -import org.springframework.vault.util.TestWebClientFactory; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * Integration tests for {@link AppIdAuthentication} using - * {@link AuthenticationStepsOperator}. - * - * @author Mark Paluch - */ -class AppIdAuthenticationOperatorIntegrationTests extends AppIdAuthenticationIntegrationTestBase { - - WebClient webClient = TestWebClientFactory.create(Settings.createSslConfiguration()); - - @Test - void authenticationStepsShouldLoginSuccessfully() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("myapp") // - .userIdMechanism(new StaticUserId("static-userid-value")) // - .build(); - - AuthenticationStepsOperator supplier = new AuthenticationStepsOperator( - AppIdAuthentication.createAuthenticationSteps(options), this.webClient); - - supplier.getVaultToken() // - .as(StepVerifier::create) // - .expectNextCount(1) // - .verifyComplete(); - } - - @Test - void authenticationStepsLoginShouldFail() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("wrong") // - .userIdMechanism(new StaticUserId("wrong")) // - .build(); - - AuthenticationStepsOperator supplier = new AuthenticationStepsOperator( - AppIdAuthentication.createAuthenticationSteps(options), this.webClient); - - supplier.getVaultToken() // - .as(StepVerifier::create) // - .expectError() // - .verify(); - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationStepsIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationStepsIntegrationTests.java deleted file mode 100644 index 7f0f7dc6..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationStepsIntegrationTests.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2017-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import org.junit.jupiter.api.Test; - -import org.springframework.vault.VaultException; -import org.springframework.vault.support.VaultToken; -import org.springframework.vault.util.Settings; -import org.springframework.vault.util.TestRestTemplateFactory; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.*; - -/** - * Integration tests for {@link AppIdAuthentication} using - * {@link AuthenticationStepsExecutor}. - * - * @author Mark Paluch - */ -class AppIdAuthenticationStepsIntegrationTests extends AppIdAuthenticationIntegrationTestBase { - - @Test - void authenticationStepsShouldLoginSuccessfully() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("myapp") // - .userIdMechanism(new StaticUserId("static-userid-value")) // - .build(); - - RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration()); - - AuthenticationStepsExecutor executor = new AuthenticationStepsExecutor( - AppIdAuthentication.createAuthenticationSteps(options), restTemplate); - - VaultToken login = executor.login(); - - assertThat(login.getToken()).isNotEmpty(); - } - - @Test - void authenticationStepsLoginShouldFail() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("wrong") // - .userIdMechanism(new StaticUserId("wrong")) // - .build(); - - RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration()); - - AuthenticationStepsExecutor executor = new AuthenticationStepsExecutor( - AppIdAuthentication.createAuthenticationSteps(options), restTemplate); - - assertThatExceptionOfType(VaultException.class).isThrownBy(executor::login); - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationUnitTests.java deleted file mode 100644 index 255892aa..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/AppIdAuthenticationUnitTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.vault.VaultException; -import org.springframework.vault.client.VaultClients; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.*; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; -import static org.springframework.test.web.client.response.MockRestResponseCreators.*; - -/** - * Unit tests for {@link AppIdAuthentication}. - * - * @author Mark Paluch - */ -class AppIdAuthenticationUnitTests { - - RestTemplate restTemplate; - - MockRestServiceServer mockRest; - - @BeforeEach - void before() { - - RestTemplate restTemplate = VaultClients.createRestTemplate(); - restTemplate.setUriTemplateHandler(new VaultClients.PrefixAwareUriBuilderFactory()); - this.mockRest = MockRestServiceServer.createServer(restTemplate); - this.restTemplate = restTemplate; - } - - @Test - void loginShouldObtainTokenWithStaticUserId() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("hello") // - .userIdMechanism(new StaticUserId("world")) // - .build(); - - this.mockRest.expect(requestTo("/auth/app-id/login")) - .andExpect(method(HttpMethod.POST)) - .andExpect(jsonPath("$.app_id").value("hello")) - .andExpect(jsonPath("$.user_id").value("world")) - .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON) - .body("{" + "\"auth\":{\"client_token\":\"my-token\"}" + "}")); - - AppIdAuthentication authentication = new AppIdAuthentication(options, this.restTemplate); - - VaultToken login = authentication.login(); - assertThat(login).isInstanceOf(LoginToken.class); - assertThat(login.getToken()).isEqualTo("my-token"); - } - - @Test - void loginShouldFail() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("hello") // - .userIdMechanism(new StaticUserId("world")) // - .build(); - - this.mockRest.expect(requestTo("/auth/app-id/login")) // - .andRespond(withServerError()); - - assertThatExceptionOfType(VaultException.class) - .isThrownBy(() -> new AppIdAuthentication(options, this.restTemplate).login()); - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/GcpIamAuthenticationOptionsBuilderUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/GcpIamAuthenticationOptionsBuilderUnitTests.java deleted file mode 100644 index b672702e..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/GcpIamAuthenticationOptionsBuilderUnitTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2018-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.security.PrivateKey; - -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -/** - * Unit tests for {@link GcpIamAuthenticationOptions}. - * - * @author Magnus Jungsbluth - */ -class GcpIamAuthenticationOptionsBuilderUnitTests { - - @Test - void shouldDefaultToCredentialServiceAccountId() { - - GoogleCredential credential = createGoogleCredential(); - - GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder() - .credential(credential) - .role("foo") - .build(); - - assertThat(options.getServiceAccountIdAccessor().getServiceAccountId(credential)).isEqualTo("hello@world"); - } - - @Test - void shouldAllowServiceAccountIdOverride() { - - GoogleCredential credential = createGoogleCredential(); - - GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder() - .credential(credential) - .serviceAccountId("override@foo.com") - .role("foo") - .build(); - - assertThat(options.getServiceAccountIdAccessor().getServiceAccountId(credential)).isEqualTo("override@foo.com"); - } - - @Test - void shouldAllowServiceAccountIdProviderOverride() { - - GoogleCredential credential = createGoogleCredential(); - - GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder() - .credential(credential) - .serviceAccountIdAccessor((GoogleCredential googleCredential) -> "override@foo.com") - .role("foo") - .build(); - - assertThat(options.getServiceAccountIdAccessor().getServiceAccountId(credential)).isEqualTo("override@foo.com"); - } - - @Test - void shouldDefaultToCredentialProjectId() { - - GoogleCredential credential = createGoogleCredential(); - - GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder() - .credential(credential) - .role("foo") - .build(); - - assertThat(options.getProjectIdAccessor().getProjectId(credential)).isEqualTo("project-id"); - } - - @Test - void shouldAllowProjectIdOverride() { - - GoogleCredential credential = createGoogleCredential(); - - GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder() - .credential(credential) - .projectId("my-project") - .role("foo") - .build(); - - assertThat(options.getProjectIdAccessor().getProjectId(credential)).isEqualTo("my-project"); - } - - @Test - void shouldAllowProjectIdProviderOverride() { - - GoogleCredential credential = createGoogleCredential(); - - GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder() - .credential(credential) - .projectIdAccessor((GoogleCredential googleCredential) -> "my-project") - .role("foo") - .build(); - - assertThat(options.getProjectIdAccessor().getProjectId(credential)).isEqualTo("my-project"); - } - - private static GoogleCredential createGoogleCredential() { - - GoogleCredential credential = new GoogleCredential.Builder().setServiceAccountId("hello@world") - .setServiceAccountProjectId("project-id") - .setServiceAccountPrivateKey(mock(PrivateKey.class)) - .setServiceAccountPrivateKeyId("key-id") - .build(); - - credential.setAccessToken("foobar"); - - return credential; - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/GcpIamAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/GcpIamAuthenticationUnitTests.java deleted file mode 100644 index bbbccdda..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/GcpIamAuthenticationUnitTests.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2018-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.time.Duration; - -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential.Builder; -import com.google.api.client.googleapis.testing.auth.oauth2.MockGoogleCredential; -import com.google.api.client.json.gson.GsonFactory; -import com.google.api.client.testing.http.MockHttpTransport; -import com.google.api.client.testing.http.MockLowLevelHttpResponse; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.vault.client.VaultClients; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; -import static org.springframework.test.web.client.response.MockRestResponseCreators.*; - -/** - * Unit tests for {@link GcpIamAuthentication}. - * - * @author Mark Paluch - */ -class GcpIamAuthenticationUnitTests { - - RestTemplate restTemplate; - - MockRestServiceServer mockRest; - - @BeforeEach - void before() { - - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setUriTemplateHandler(new VaultClients.PrefixAwareUriBuilderFactory()); - - this.mockRest = MockRestServiceServer.createServer(restTemplate); - this.restTemplate = restTemplate; - } - - @Test - void shouldLogin() throws NoSuchAlgorithmException { - - this.mockRest.expect(requestTo("/auth/gcp/login")) - .andExpect(method(HttpMethod.POST)) - .andExpect(jsonPath("$.role").value("dev-role")) - .andExpect(jsonPath("$.jwt").value("my-jwt")) - .andRespond(withSuccess().contentType(MediaType.APPLICATION_JSON) - .body("{" + "\"auth\":{\"client_token\":\"my-token\", \"renewable\": true, \"lease_duration\": 10}" - + "}")); - - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(1024); - KeyPair key = keyGen.generateKeyPair(); - - GoogleCredential credential = new MockGoogleCredential.Builder().setServiceAccountId("hello@world") - .setServiceAccountProjectId("foobar") - .setServiceAccountPrivateKey(key.getPrivate()) - .setServiceAccountPrivateKeyId("key-id") - .setJsonFactory(new GsonFactory()) - .setTransport(new MockHttpTransport.Builder().setLowLevelHttpResponse(createMockHttpResponse()).build()) - .build(); - credential.setAccessToken("foobar"); - - GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder() - .role("dev-role") - .credential(credential) - .build(); - GcpIamAuthentication authentication = new GcpIamAuthentication(options, this.restTemplate, - new MockHttpTransport.Builder().setLowLevelHttpResponse(createMockHttpResponse()).build()); - - VaultToken login = authentication.login(); - - assertThat(login).isInstanceOf(LoginToken.class); - assertThat(login.getToken()).isEqualTo("my-token"); - - LoginToken loginToken = (LoginToken) login; - assertThat(loginToken.isRenewable()).isTrue(); - assertThat(loginToken.getLeaseDuration()).isEqualTo(Duration.ofSeconds(10)); - } - - private MockLowLevelHttpResponse createMockHttpResponse() { - MockLowLevelHttpResponse response = new MockLowLevelHttpResponse(); - response.setStatusCode(200); - response.setContent("{\"keyId\":\"keyid\", \"signedJwt\":\"my-jwt\"}"); - return response; - } - - @Test - void shouldCreateNewGcpIamObjectInstance() throws GeneralSecurityException, IOException { - - PrivateKey privateKeyMock = mock(PrivateKey.class); - GoogleCredential credential = new Builder().setServiceAccountId("hello@world") - .setServiceAccountProjectId("foobar") - .setServiceAccountPrivateKey(privateKeyMock) - .setServiceAccountPrivateKeyId("key-id") - .build(); - credential.setAccessToken("foobar"); - - GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder() - .role("dev-role") - .credential(credential) - .build(); - - new GcpIamAuthentication(options, this.restTemplate); - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/IpAddressUserIdTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/IpAddressUserIdTests.java deleted file mode 100644 index 0e9a9ee4..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/IpAddressUserIdTests.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.util.regex.Pattern; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.*; - -/** - * Unit tests for {@link IpAddressUserId}. - * - * @author Mark Paluch - */ -class IpAddressUserIdTests { - - @Test - void shouldGenerateUppercaseSha256HexString() { - - String userId = new IpAddressUserId().createUserId(); - - assertThat(userId).matches(Pattern.compile("[0-9A-F]+")).doesNotMatch(Pattern.compile("[a-f]")); - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/authentication/MacAddressUserIdUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/authentication/MacAddressUserIdUnitTests.java deleted file mode 100644 index 91cb2c1d..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/authentication/MacAddressUserIdUnitTests.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2016-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.authentication; - -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Collections; -import java.util.List; -import java.util.regex.Pattern; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assumptions.*; - -/** - * Unit tests for {@link MacAddressUserId}. - * - * @author Mark Paluch - */ -class MacAddressUserIdUnitTests { - - @Test - void shouldGenerateUppercaseSha256HexString() { - - String userId = new MacAddressUserId().createUserId(); - - assertThat(userId).matches(Pattern.compile("[0-9A-F]+")).doesNotMatch(Pattern.compile("[a-f]")); - } - - @Test - void shouldGenerateUserIdFromNetworkInterfaceIndex() throws Exception { - - int index = getValidNetworkInterfaceIndex(); - assumeTrue(index != -1); - - String userId = new MacAddressUserId(index).createUserId(); - - assertThat(userId).matches(Pattern.compile("[0-9A-F]+")).doesNotMatch(Pattern.compile("[a-f]")); - } - - /** - * Obtain index for {@link NetworkInterface} with a HardwareAddress. - * @return -1 if none, otherwise index. - * @throws SocketException - */ - private int getValidNetworkInterfaceIndex() throws SocketException { - - List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); - - int index = -1; - - for (int i = 0; i < interfaces.size(); i++) { - if (interfaces.get(i).getHardwareAddress() != null) { - index = i; - break; - } - } - return index; - } - -} diff --git a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppIdAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppIdAuthenticationUnitTests.java deleted file mode 100644 index fb74b918..00000000 --- a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppIdAuthenticationUnitTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2017-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.vault.config; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.vault.authentication.AppIdAuthentication; -import org.springframework.vault.authentication.ClientAuthentication; - -import static org.assertj.core.api.Assertions.*; - -/** - * Unit tests for {@link EnvironmentVaultConfiguration} with AppId authentication. - * - * @author Mark Paluch - */ -@ExtendWith(SpringExtension.class) -@TestPropertySource(properties = { "vault.uri=https://localhost:8123", "vault.authentication=appid", - "vault.app-id.user-id=IP_ADDRESS", "vault.app-id.app-id=foo" }) -class EnvironmentVaultConfigurationAppIdAuthenticationUnitTests { - - @Configuration - @Import(EnvironmentVaultConfiguration.class) - static class ApplicationConfiguration { - - } - - @Autowired - EnvironmentVaultConfiguration configuration; - - @Test - void shouldConfigureAuthentication() { - - ClientAuthentication clientAuthentication = this.configuration.clientAuthentication(); - - assertThat(clientAuthentication).isInstanceOf(AppIdAuthentication.class); - } - -} diff --git a/src/main/antora/modules/ROOT/nav.adoc b/src/main/antora/modules/ROOT/nav.adoc index 7d6822a0..eee5b105 100644 --- a/src/main/antora/modules/ROOT/nav.adoc +++ b/src/main/antora/modules/ROOT/nav.adoc @@ -2,7 +2,6 @@ * xref:introduction/introduction.adoc[] ** xref:introduction/getting-started.adoc[] ** xref:introduction/dependencies.adoc[] -** xref:introduction/new-features.adoc[] * xref:vault/vault.adoc[] ** xref:vault/imperative-template.adoc[] ** xref:vault/vault-secret-engines.adoc[] @@ -13,5 +12,4 @@ ** xref:vault/authentication.adoc[] ** xref:vault/spring-security.adoc[] - * xref:attachment$api/java/index.html[Javadoc,role=link-external,window=_blank] diff --git a/src/main/antora/modules/ROOT/pages/introduction/new-features.adoc b/src/main/antora/modules/ROOT/pages/introduction/new-features.adoc deleted file mode 100644 index ba357755..00000000 --- a/src/main/antora/modules/ROOT/pages/introduction/new-features.adoc +++ /dev/null @@ -1,76 +0,0 @@ -[[new-features]] -= New & Noteworthy - -[[new-features.3-0-0]] -== What's new in Spring Vault 3.0 - -* Upgrade to Spring Framework 6 and Java 17 baseline -* Upgrade to AWS SDK 2. - -== What's new in Spring Vault 2.4 - -* Support for xref:vault/authentication.adoc#vault.authentication.userpass[Username/Password authentication] for Username/Password, LDAP, Okta, and RADIUS authentication. -* Support of versioned Key/Value secrets engines for Vault repositories. -* xref:vault/vault-repositories.adoc#repositories.optimistic-locking[Optimistic locking support through Vault repositories using versioned Key/Value secrets engines]. - -[[new-features.2-3-0]] -== What's new in Spring Vault 2.3 - -* Support for PEM-encoded certificates for keystore and truststore usage. -* `ReactiveVaultEndpointProvider` for non-blocking lookup of `VaultEndpoint`. -* `VaultKeyValueMetadataOperations` for Key-Value metadata interaction. -* Support for `transform` secrets engine (Enterprise Feature). -* Documentation of xref:vault/vault-secret-engines.adoc[how to use Vault secret backends]. -* Login credentials for Kubernetes and PCF authentication are reloaded for each login attempt. -* `SecretLeaseContainer` publishes `SecretLeaseRotatedEvent` instead of `SecretLeaseExpiredEvent` and `SecretLeaseCreatedEvent` on successful secret rotation. -* `AbstractVaultConfiguration.threadPoolTaskScheduler()` bean type changed to `TaskSchedulerWrapper` instead of `ThreadPoolTaskScheduler`. -* Since 2.3.2: `GcpIamCredentialsAuthentication` - -[[new-features.2-2-0]] -== What's new in Spring Vault 2.2 - -* Support for Key-Value v2 (versioned secrets engine) secrets through `@VaultPropertySource`. -* SpEL support in `@Secret`. -* Add support for Jetty as reactive HttpClient. -* `LifecycleAwareSessionManager` and `ReactiveLifecycleAwareSessionManager` emit now ``AuthenticationEvent``s. -* xref:vault/vault-secret-engines.adoc#vault.authentication.pcf[PCF Authentication]. -* Deprecation of `AppIdAuthentication`. -Use `AppRoleAuthentication` instead as recommended by HashiCorp Vault. -* `CubbyholeAuthentication` and wrapped `AppRoleAuthentication` now use `sys/wrapping/unwrap` endpoints by default. -* Kotlin Coroutines support for `ReactiveVaultOperations`. - -[[new-features.2-1-0]] -== What's new in Spring Vault 2.1 - -* xref:vault/authentication.adoc#vault.authentication.gcpgce[GCP Compute], xref:vault/authentication.adoc#vault.authentication.gcpiam[GCP IAM], and xref:vault/authentication.adoc#vault.authentication.azuremsi[Azure] authentication. -* Template API support for versioned and unversioned Key/Value secrets engines and for Vault wrapping operations. -* Support full pull mode in reactive AppRole authentication. -* Improved Exception hierarchy for Vault login failures. - -[[new-features.2-0-0]] -== What's new in Spring Vault 2.0 - -* Authentication steps DSL to xref:vault/authentication.adoc#vault.authentication.steps[compose authentication flows]. -* xref:vault/reactive-template.adoc[Reactive Vault client] via `ReactiveVaultOperations`. -* xref:vault/vault-repositories.adoc[Vault repository support] based on Spring Data KeyValue. -* Transit batch encrypt and decrypt support. -* Policy management for policies stored as JSON. -* Support CSR signing, certificate revocation and CRL retrieval. -* xref:vault/authentication.adoc#vault.authentication.kubernetes[Kubernetes authentication]. -* RoleId/SecretId unwrapping for xref:vault/authentication.adoc#vault.authentication.approle[AppRole authentication]. -* Spring Security integration with transit secrets engine-based `BytesKeyGenerator` and `BytesEncryptor`. - -[[new-features.1-1-0]] -== What's new in Spring Vault 1.1.0 - -* AWS IAM authentication. -* Configuration of encryption/decryption versions for transit keys. -* Pull mode for AppRole authentication. -* Transit batch encrypt and decrypt support. -* TTL-based generic secret rotation. - -[[new-features.1-0-0]] -== What's new in Spring Vault 1.0 - -* Initial Vault support. - diff --git a/src/main/antora/modules/ROOT/pages/vault/authentication.adoc b/src/main/antora/modules/ROOT/pages/vault/authentication.adoc index 7a41fcb8..393bb53d 100644 --- a/src/main/antora/modules/ROOT/pages/vault/authentication.adoc +++ b/src/main/antora/modules/ROOT/pages/vault/authentication.adoc @@ -80,127 +80,12 @@ See also: * https://www.vaultproject.io/docs/concepts/tokens.html[Vault Documentation: Tokens] * https://www.vaultproject.io/docs/auth/token.html[Vault Documentation: Using the Token auth backend] -[[vault.authentication.appid]] -== AppId authentication - -NOTE: AppId authentication is deprecated by Vault. Use <> instead. - -Vault supports https://www.vaultproject.io/docs/auth/app-id.html[AppId] -authentication that consists of two hard to guess tokens. The AppId -defaults to `spring.application.name` that is statically configured. -The second token is the UserId which is a part determined by the application, -usually related to the runtime environment. IP address, Mac address or a -Docker container name are good examples. Spring Vault supports -IP address, Mac address and static UserId's (e.g. supplied via System properties). -The IP and Mac address are represented as Hex-encoded SHA256 hash. - -IP address-based UserId's use the local host's IP address. - -==== -[source,java] ----- -@Configuration -class AppConfig extends AbstractVaultConfiguration { - - // … - - @Override - public ClientAuthentication clientAuthentication() { - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("myapp") - .userIdMechanism(new IpAddressUserId()) - .build(); - - return new AppIdAuthentication(options, restOperations()); - } - - // … -} ----- -==== - -The corresponding command to generate the IP address UserId from a command line is: - ----- -$ echo -n 192.168.99.1 | sha256sum ----- - -NOTE: Including the line break of `echo` leads to a different hash value -so make sure to include the `-n` flag. - -Mac address-based UserId's obtain their network device from the -localhost-bound device. The configuration also allows specifying -a `network-interface` hint to pick the right device. The value of -`network-interface` is optional and can be either an interface -name or interface index (0-based). - -==== -[source,java] ----- -@Configuration -class AppConfig extends AbstractVaultConfiguration { - - // … - - @Override - public ClientAuthentication clientAuthentication() { - - AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder() - .appId("myapp") - .userIdMechanism(new MacAddressUserId()) - .build(); - - return new AppIdAuthentication(options, restOperations()); - } - - // … -} ----- -==== - -The corresponding command to generate the Mac address UserId from a command line is: - ----- -$ echo -n 0AFEDE1234AC | sha256sum ----- - -NOTE: The Mac address is specified uppercase and without colons. -Including the line break of `echo` leads to a different hash value -so make sure to include the `-n` flag. - -=== Custom UserId - -A more advanced approach lets you implementing your own `AppIdUserIdMechanism`. -This class must be on your classpath and must implement -the `org.springframework.vault.authentication.AppIdUserIdMechanism` interface -and the `createUserId` method. Spring Vault will obtain the UserId -by calling `createUserId` each time it authenticates using AppId to -obtain a token. - -==== -[source,java] -.MyUserIdMechanism.java ----- -public class MyUserIdMechanism implements AppIdUserIdMechanism { - - @Override - public String createUserId() { - - String userId = … - return userId; - } -} ----- -==== - -See also: https://www.vaultproject.io/docs/auth/app-id.html[Vault Documentation: Using the App ID auth backend] - [[vault.authentication.approle]] == AppRole authentication https://www.vaultproject.io/docs/auth/app-id.html[AppRole] allows machine -authentication, like the deprecated (since Vault 0.6.1) <>. -AppRole authentication consists of two hard to guess (secret) tokens: RoleId and SecretId. +authentication. AppRole authentication consists of two hard to guess (secret) +tokens: RoleId and SecretId. Spring Vault supports AppRole authentication by providing either RoleId only or together with a provided SecretId and fetching RoleId/SecretId from Vault diff --git a/src/main/antora/modules/ROOT/pages/vault/imperative-template.adoc b/src/main/antora/modules/ROOT/pages/vault/imperative-template.adoc index 8b1fffc7..29860d8b 100644 --- a/src/main/antora/modules/ROOT/pages/vault/imperative-template.adoc +++ b/src/main/antora/modules/ROOT/pages/vault/imperative-template.adoc @@ -182,7 +182,7 @@ vault.token=00000000-0000-0000-0000-000000000000 ** Truststore type: `vault.ssl.trust-store-type` (optional, typically `jks`, supports also `pem`) ** Enabled SSL/TLS protocols: `vault.ssl.enabled-protocols` (since 2.3.2, optional, protocols separated with comma) ** Enabled SSL/TLS cipher suites: `vault.ssl.enabled-cipher-suites` (since 2.3.2, optional, cipher suites separated with comma) -* Authentication method: `vault.authentication` (defaults to `TOKEN`, supported authentication methods are: `TOKEN`, `APPID`, `APPROLE`, `AWS_EC2`, `AWS_IAM`, `AZURE`, `CERT`, `CUBBYHOLE`, `KUBERNETES`) +* Authentication method: `vault.authentication` (defaults to `TOKEN`, supported authentication methods are: `TOKEN`, `APPROLE`, `AWS_EC2`, `AWS_IAM`, `AZURE`, `CERT`, `CUBBYHOLE`, `KUBERNETES`) **Authentication-specific property keys** @@ -190,13 +190,6 @@ vault.token=00000000-0000-0000-0000-000000000000 * Vault Token: `vault.token` -**<>** - -* AppId path: `vault.app-id.app-id-path` (defaults to `app-id`) -* AppId: `vault.app-id.app-id` -* UserId: `vault.app-id.user-id`. `MAC_ADDRESS` and `IP_ADDRESS` use `MacAddressUserId`, respective `IpAddressUserId` user id mechanisms. -Any other value is used with `StaticUserId`. - **<>** * AppRole path: `vault.app-role.app-role-path` (defaults to `approle`)