Polishing.

Refactor AuthenticationSteps creation into static factory method.

Extend tests, add documentation.

See gh-821
Original pull request: gh-853
This commit is contained in:
Mark Paluch
2024-06-06 12:08:26 +02:00
parent fdcab61e3a
commit 114f944faa
4 changed files with 92 additions and 12 deletions

View File

@@ -16,8 +16,10 @@
package org.springframework.vault.authentication;
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.VaultException;
import org.springframework.vault.support.VaultResponse;
@@ -30,6 +32,7 @@ import org.springframework.web.client.RestOperations;
* personal access token.
*
* @author Nanne Baars
* @author Mark Paluch
* @since 3.2
* @see GitHubAuthentication
* @see RestOperations
@@ -58,11 +61,24 @@ public class GitHubAuthentication implements ClientAuthentication, Authenticatio
this.restOperations = restOperations;
}
/**
* Creates a {@link AuthenticationSteps} for GitHub authentication given
* {@link GitHubAuthenticationOptions}.
* @param options must not be {@literal null}.
* @return {@link AuthenticationSteps} for github authentication.
*/
public static AuthenticationSteps createAuthenticationSteps(GitHubAuthenticationOptions options) {
Assert.notNull(options, "GitHubAuthentication must not be null");
return AuthenticationSteps.fromSupplier(options.getTokenSupplier())
.map(GitHubAuthentication::getGitHubLogin)
.login(AuthenticationUtil.getLoginPath(options.getPath()));
}
@Override
public AuthenticationSteps getAuthenticationSteps() {
return AuthenticationSteps.fromSupplier(options.getTokenSupplier())
.map(token -> getGitHubLogin(token))
.login(AuthenticationUtil.getLoginPath(this.options.getPath()));
return createAuthenticationSteps(options);
}
@Override

View File

@@ -27,7 +27,6 @@ import org.springframework.util.Assert;
* Instances of this class are immutable once constructed.
*
* @author Nanne Baars
* @author Mark Paluch
* @since 3.2
* @see GitHubAuthentication
* @see #builder()

View File

@@ -53,10 +53,13 @@ class GitHubAuthenticationIntegrationTest extends IntegrationTestSupport {
prepare().mountAuth("github");
}
prepare().getVaultOperations()
.doWithSession(
restOperations -> restOperations.postForEntity("auth/github/config", Map.of("organization_id", 1,
"base_url", "http://localhost:%d".formatted(gitHubMockServer.getPort())), Map.class));
gitHubMockServer.start();
prepare().getVaultOperations().doWithSession(restOperations -> {
Map<String, String> config = Map.of("organization", "foo", "organization_id", "" + organizationId,
"base_url", "http://localhost:%d".formatted(gitHubMockServer.getPort()));
return restOperations.postForEntity("auth/github/config", config, Map.class);
});
}
@AfterEach
@@ -66,21 +69,45 @@ class GitHubAuthenticationIntegrationTest extends IntegrationTestSupport {
@Test
void shouldLoginSuccessfully() {
GitHubAuthenticationOptions options = GitHubAuthenticationOptions.builder()
.tokenSupplier(() -> "TOKEN")
.build();
RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration());
setupGithubMockServer(gitHubUserResponse(), gitHubOrganizationResponse(organizationId),
gitHubTeamResponse(organizationId));
GitHubAuthentication authentication = new GitHubAuthentication(
GitHubAuthenticationOptions.builder().tokenSupplier(() -> "TOKEN").build(), restTemplate);
GitHubAuthentication authentication = new GitHubAuthentication(options, restTemplate);
VaultToken loginToken = authentication.login();
assertThat(loginToken.getToken()).isNotNull();
}
@Test
void shouldFailIfOrganizationIsNotTheSame() {
void shouldLoginUsingAuthenticationSteps() {
GitHubAuthenticationOptions options = GitHubAuthenticationOptions.builder()
.tokenSupplier(() -> "TOKEN")
.build();
RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration());
var wrongOrganizationId = organizationId + 1;
setupGithubMockServer(gitHubUserResponse(), gitHubOrganizationResponse(organizationId),
gitHubTeamResponse(organizationId));
AuthenticationSteps steps = GitHubAuthentication.createAuthenticationSteps(options);
AuthenticationStepsExecutor executor = new AuthenticationStepsExecutor(steps, restTemplate);
VaultToken loginToken = executor.login();
assertThat(loginToken.getToken()).isNotNull();
}
@Test
void shouldFailIfOrganizationIsNotTheSame() {
RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration());
int wrongOrganizationId = organizationId + 1;
setupGithubMockServer(gitHubUserResponse(), gitHubOrganizationResponse(wrongOrganizationId),
gitHubTeamResponse(wrongOrganizationId));

View File

@@ -537,6 +537,44 @@ See also:
* https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signJwt
* https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts/signJwt (deprecated)
[[vault.authentication.github]]
== GitHub Authentication
The https://www.vaultproject.io/docs/auth/github.html[github]
auth backend provides an authentication mechanism based on GitHub tokens.
Vault does not support an OAuth workflow to generate GitHub tokens,
so it does not act as a GitHub application.
The authentication mechanism requires a GitHub token (or a supplier)
to pass on the token to Vault which then authenticates against your GitHub
account.
====
[source,java]
----
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
GitHubAuthentication options = GitHubAuthentication.builder()
.token(…).build();
return new GitHubAuthentication(options, restOperations());
}
// …
}
----
====
See also:
* https://www.vaultproject.io/api-docs/auth/github[Vault Documentation: GitHub auth method]
[[vault.authentication.pcf]]
== PCF authentication