diff --git a/src/main/java/com/bettercloud/vault/api/Auth.java b/src/main/java/com/bettercloud/vault/api/Auth.java index 0e193c8e..a811b137 100644 --- a/src/main/java/com/bettercloud/vault/api/Auth.java +++ b/src/main/java/com/bettercloud/vault/api/Auth.java @@ -857,6 +857,71 @@ public AuthResponse loginByGithub(final String githubToken, final String githubA } } + /** + *
Basic login operation to authenticate to an JWT/OIDC backend. Example usage:
+ * + *
+ * {@code
+ * final AuthResponse response = vault.auth().loginByJWT("role", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "jwt");
+ *
+ * final String token = response.getAuthClientToken();
+ * }
+ *
+ *
+ * @param role The jwt role used for authentication
+ * @param jwt Signed JSON Web Token (JWT)
+ * @param path Path the JWT auth backend is mounted
+ * @return The auth token, with additional response metadata
+ * @throws VaultException If any error occurs, or unexpected response received from Vault
+ */
+ // TODO: Needs integration test coverage if possible
+ public AuthResponse loginByJWT(final String role, final String jwt, final String path) throws VaultException {
+ int retryCount = 0;
+
+ while (true) {
+ try {
+ // HTTP request to Vault
+ final String requestJson = Json.object()
+ .add("role", role)
+ .add("jwt", jwt)
+ .toString();
+ final RestResponse restResponse = new Rest()
+ .url(config.getAddress() + "/v1/auth/" + path + "/login")
+ .body(requestJson.getBytes("UTF-8"))
+ .connectTimeoutSeconds(config.getOpenTimeout())
+ .readTimeoutSeconds(config.getReadTimeout())
+ .sslVerification(config.getSslConfig().isVerify())
+ .sslContext(config.getSslConfig().getSslContext())
+ .post();
+
+ // Validate restResponse
+ if (restResponse.getStatus() != 200) {
+ throw new VaultException("Vault responded with HTTP status code: " + restResponse.getStatus(), restResponse.getStatus());
+ }
+ final String mimeType = restResponse.getMimeType() == null ? "null" : restResponse.getMimeType();
+ if (!mimeType.equals("application/json")) {
+ throw new VaultException("Vault responded with MIME type: " + mimeType, restResponse.getStatus());
+ }
+ return new AuthResponse(restResponse, retryCount);
+ } catch (Exception e) {
+ // If there are retries to perform, then pause for the configured interval and then execute the loop again...
+ if (retryCount < config.getMaxRetries()) {
+ retryCount++;
+ try {
+ final int retryIntervalMilliseconds = config.getRetryIntervalMilliseconds();
+ Thread.sleep(retryIntervalMilliseconds);
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+ } else if (e instanceof VaultException) {
+ // ... otherwise, give up.
+ throw (VaultException) e;
+ } else {
+ throw new VaultException(e);
+ }
+ }
+ }
+ }
/**
* Basic login operation to authenticate to an GCP backend. Example usage:
* diff --git a/src/test-integration/java/com/bettercloud/vault/util/VaultContainer.java b/src/test-integration/java/com/bettercloud/vault/util/VaultContainer.java index f86519c7..8f5a6c5f 100644 --- a/src/test-integration/java/com/bettercloud/vault/util/VaultContainer.java +++ b/src/test-integration/java/com/bettercloud/vault/util/VaultContainer.java @@ -34,7 +34,7 @@ public class VaultContainer implements TestRule, TestConstants { /** Establishes a running Docker container, hosting a Vault server instance. */ public VaultContainer() { - container = new GenericContainer("vault:0.9.1") + container = new GenericContainer("vault:0.10.4") .withClasspathResourceMapping("/startup.sh", CONTAINER_STARTUP_SCRIPT, BindMode.READ_ONLY) .withClasspathResourceMapping("/config.json", CONTAINER_CONFIG_FILE, BindMode.READ_ONLY) .withClasspathResourceMapping("/libressl.conf", CONTAINER_OPENSSL_CONFIG_FILE, BindMode.READ_ONLY)