Provide static AuthenticationSteps factory methods in authentication implementations.

See gh-107.
This commit is contained in:
Mark Paluch
2017-07-06 20:26:27 +02:00
parent ef1fc0761c
commit 5ae83d34e6
7 changed files with 174 additions and 65 deletions

View File

@@ -66,11 +66,35 @@ public class AppIdAuthentication implements ClientAuthentication,
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("auth/{mount}/login", options.getPath());
}
@Override
public VaultToken login() {
return createTokenUsingAppId();
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
return createAuthenticationSteps(options);
}
private VaultToken createTokenUsingAppId() {
Map<String, String> login = getAppIdLogin(options.getAppId(), options
@@ -90,19 +114,13 @@ public class AppIdAuthentication implements ClientAuthentication,
}
}
public AuthenticationSteps getAuthenticationSteps() {
return AuthenticationSteps.fromSupplier(
() -> getAppIdLogin(options.getAppId(), options.getUserIdMechanism()
.createUserId())) //
.login("auth/{mount}/login", options.getPath());
}
private Map<String, String> getAppIdLogin(String appId, String userId) {
private static Map<String, String> getAppIdLogin(String appId, String userId) {
Map<String, String> login = new HashMap<>();
login.put("app_id", appId);
login.put("user_id", userId);
return login;
}
}

View File

@@ -68,11 +68,34 @@ public class AppRoleAuthentication implements ClientAuthentication,
this.restOperations = restOperations;
}
/**
* Creates a {@link AuthenticationSteps} for AppRole authentication given
* {@link AppRoleAuthenticationOptions}.
*
* @param options must not be {@literal null}.
* @return {@link AuthenticationSteps} for AppRole authentication.
* @since 2.0
*/
public static AuthenticationSteps createAuthenticationSteps(
AppRoleAuthenticationOptions options) {
Assert.notNull(options, "AppRoleAuthenticationOptions must not be null");
return AuthenticationSteps.fromSupplier(
() -> getAppRoleLogin(options.getRoleId(), options.getSecretId())) //
.login("auth/{mount}/login", options.getPath());
}
@Override
public VaultToken login() {
return createTokenUsingAppRole();
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
return createAuthenticationSteps(options);
}
private VaultToken createTokenUsingAppRole() {
Map<String, String> login = getAppRoleLogin(options.getRoleId(),
@@ -92,21 +115,15 @@ public class AppRoleAuthentication implements ClientAuthentication,
}
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
return AuthenticationSteps.fromSupplier(
() -> getAppRoleLogin(options.getRoleId(), options.getSecretId())) //
.login("auth/{mount}/login", options.getPath());
}
private Map<String, String> getAppRoleLogin(String roleId, String secretId) {
private static Map<String, String> getAppRoleLogin(String roleId, String secretId) {
Map<String, String> login = new HashMap<>();
login.put("role_id", roleId);
if (secretId != null) {
login.put("secret_id", secretId);
}
return login;
}
}

View File

@@ -25,6 +25,7 @@ package org.springframework.vault.authentication;
* @since 2.0
* @see AuthenticationSteps
*/
@FunctionalInterface
public interface AuthenticationStepsFactory {
/**

View File

@@ -19,6 +19,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -94,11 +95,64 @@ public class AwsEc2Authentication implements ClientAuthentication,
this.awsMetadataRestOperations = awsMetadataRestOperations;
}
/**
* Creates a {@link AuthenticationSteps} for AWS-EC2 authentication given
* {@link AwsEc2AuthenticationOptions}.
*
* @param options must not be {@literal null}.
* @return {@link AuthenticationSteps} for AWS-EC2 authentication.
* @since 2.0
*/
public static AuthenticationSteps createAuthenticationSteps(
AwsEc2AuthenticationOptions options) {
Assert.notNull(options, "AwsEc2AuthenticationOptions must not be null");
AtomicReference<char[]> nonce = new AtomicReference<>(EMPTY);
return createAuthenticationSteps(options, nonce, () -> doCreateNonce(options));
}
protected static AuthenticationSteps createAuthenticationSteps(
AwsEc2AuthenticationOptions options, AtomicReference<char[]> nonce,
Supplier<char[]> nonceSupplier) {
return AuthenticationSteps
.fromHttpRequest(
HttpRequestBuilder.get(
options.getIdentityDocumentUri().toString()).as(
String.class)) //
.map(pkcs7 -> pkcs7.replaceAll("\\r", "")) //
.map(pkcs7 -> pkcs7.replace("\\n", "")) //
.map(pkcs7 -> {
Map<String, String> login = new HashMap<>();
if (StringUtils.hasText(options.getRole())) {
login.put("role", options.getRole());
}
if (Objects.equals(nonce.get(), EMPTY)) {
nonce.compareAndSet(EMPTY, nonceSupplier.get());
}
login.put("nonce", new String(nonce.get()));
login.put("pkcs7", pkcs7);
return login;
}).login("auth/{mount}/login", options.getPath());
}
@Override
public VaultToken login() throws VaultException {
return createTokenUsingAwsEc2();
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
return createAuthenticationSteps(this.options, this.nonce, this::createNonce);
}
@SuppressWarnings("unchecked")
private VaultToken createTokenUsingAwsEc2() {
@@ -132,33 +186,6 @@ public class AwsEc2Authentication implements ClientAuthentication,
}
}
public AuthenticationSteps getAuthenticationSteps() {
return AuthenticationSteps
.fromHttpRequest(
HttpRequestBuilder.get(
options.getIdentityDocumentUri().toString()).as(
String.class))
.map(pkcs7 -> pkcs7.replaceAll("\\r", "").replace("\\n", ""))
.map(pkcs7 -> {
Map<String, String> login = new HashMap<>();
if (StringUtils.hasText(options.getRole())) {
login.put("role", options.getRole());
}
if (Objects.equals(this.nonce.get(), EMPTY)) {
this.nonce.compareAndSet(EMPTY, createNonce());
}
login.put("nonce", new String(this.nonce.get()));
login.put("pkcs7", pkcs7);
return login;
}).login("auth/{mount}/login", options.getPath());
}
protected Map<String, String> getEc2Login() {
Map<String, String> login = new HashMap<>();
@@ -167,15 +194,15 @@ public class AwsEc2Authentication implements ClientAuthentication,
login.put("role", options.getRole());
}
if (this.nonce.get() == EMPTY) {
if (Objects.equals(this.nonce.get(), EMPTY)) {
this.nonce.compareAndSet(EMPTY, createNonce());
}
login.put("nonce", new String(this.nonce.get()));
try {
String pkcs7 = awsMetadataRestOperations.getForObject(
options.getIdentityDocumentUri(), String.class);
String pkcs7 = this.awsMetadataRestOperations.getForObject(
this.options.getIdentityDocumentUri(), String.class);
if (StringUtils.hasText(pkcs7)) {
login.put("pkcs7", pkcs7.replaceAll("\\r", "").replace("\\n", ""));
}
@@ -190,6 +217,10 @@ public class AwsEc2Authentication implements ClientAuthentication,
}
protected char[] createNonce() {
return doCreateNonce(this.options);
}
private static char[] doCreateNonce(AwsEc2AuthenticationOptions options) {
return options.getNonce().getValue();
}
}

View File

@@ -55,11 +55,26 @@ public class ClientCertificateAuthentication implements ClientAuthentication,
this.restOperations = restOperations;
}
/**
* Creates a {@link AuthenticationSteps} for client certificate authentication.
*
* @return {@link AuthenticationSteps} for client certificate authentication.
* @since 2.0
*/
public static AuthenticationSteps createAuthenticationSteps() {
return AuthenticationSteps.just(post("auth/cert/login").as(VaultResponse.class));
}
@Override
public VaultToken login() {
return createTokenUsingTlsCertAuthentication("cert");
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
return createAuthenticationSteps();
}
private VaultToken createTokenUsingTlsCertAuthentication(String path) {
try {
@@ -76,9 +91,4 @@ public class ClientCertificateAuthentication implements ClientAuthentication,
VaultResponses.getError(e.getResponseBodyAsString())));
}
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
return AuthenticationSteps.just(post("auth/cert/login").as(VaultResponse.class));
}
}

View File

@@ -162,12 +162,34 @@ public class CubbyholeAuthentication implements ClientAuthentication,
this.restOperations = restOperations;
}
/**
* Creates a {@link AuthenticationSteps} for cubbyhole authentication given
* {@link CubbyholeAuthenticationOptions}.
*
* @param options must not be {@literal null}.
* @return {@link AuthenticationSteps} for cubbyhole authentication.
* @since 2.0
*/
public static AuthenticationSteps createAuthenticationSteps(
CubbyholeAuthenticationOptions options) {
Assert.notNull(options, "CubbyholeAuthenticationOptions must not be null");
HttpRequest<VaultResponse> initialRequest = get(options.getPath()) //
.with(VaultHttpHeaders.from(options.getInitialToken())) //
.as(VaultResponse.class);
return AuthenticationSteps.fromHttpRequest(initialRequest) //
.map(VaultResponseSupport::getData) //
.login(map -> getToken(options, map));
}
@Override
public VaultToken login() throws VaultException {
Map<String, Object> data = lookupToken();
VaultToken tokenToUse = getToken(data);
VaultToken tokenToUse = getToken(this.options, data);
if (shouldEnhanceTokenWithSelfLookup(tokenToUse)) {
@@ -180,15 +202,9 @@ public class CubbyholeAuthentication implements ClientAuthentication,
return tokenToUse;
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
HttpRequest<VaultResponse> initialRequest = get(options.getPath()) //
.with(VaultHttpHeaders.from(options.getInitialToken())) //
.as(VaultResponse.class);
return AuthenticationSteps.fromHttpRequest(initialRequest) //
.map(VaultResponseSupport::getData) //
.login(this::getToken);
return createAuthenticationSteps(options);
}
private Map<String, Object> lookupToken() {
@@ -227,7 +243,8 @@ public class CubbyholeAuthentication implements ClientAuthentication,
return true;
}
private VaultToken getToken(Map<String, Object> data) {
private static VaultToken getToken(CubbyholeAuthenticationOptions options,
Map<String, Object> data) {
if (options.isWrappedToken()) {

View File

@@ -54,13 +54,28 @@ public class TokenAuthentication implements ClientAuthentication,
this.token = token;
}
/**
* Creates a {@link AuthenticationSteps} for token authentication given
* {@link VaultToken}.
*
* @param token must not be {@literal null}.
* @return {@link AuthenticationSteps} for token authentication.
* @since 2.0
*/
public static AuthenticationSteps createAuthenticationSteps(VaultToken token) {
Assert.notNull(token, "VaultToken must not be null");
return AuthenticationSteps.just(token);
}
@Override
public VaultToken login() {
return token;
return this.token;
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
return AuthenticationSteps.just(token);
return createAuthenticationSteps(this.token);
}
}