Skip to content

Commit af060ac

Browse files
committed
Default to IMDSv2 for AWS-EC2 metadata retrieval.
See gh-865
1 parent dac9e36 commit af060ac

File tree

2 files changed

+47
-22
lines changed

2 files changed

+47
-22
lines changed

spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2AuthenticationOptions.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
* Authentication options provide the path, the Identity Document URI and an optional
3030
* role. {@link AwsEc2AuthenticationOptions} can be constructed using {@link #builder()}.
3131
* Instances of this class are immutable once constructed.
32+
* <p>
33+
* Metadata retrieval defaults to IMDSv2 (session-token).
3234
*
3335
* @author Mark Paluch
3436
* @see AwsEc2Authentication
@@ -94,7 +96,7 @@ public class AwsEc2AuthenticationOptions {
9496

9597
private AwsEc2AuthenticationOptions() {
9698
this(DEFAULT_AWS_AUTHENTICATION_PATH, DEFAULT_PKCS7_IDENTITY_DOCUMENT_URI, "", Nonce.generated(),
97-
Duration.ofMinutes(1), DEFAULT_IMDSV2_TOKEN_URI, InstanceMetadataServiceVersion.V1);
99+
Duration.ofMinutes(1), DEFAULT_IMDSV2_TOKEN_URI, InstanceMetadataServiceVersion.V2);
98100
}
99101

100102
private AwsEc2AuthenticationOptions(String path, URI identityDocumentUri, @Nullable String role, Nonce nonce,
@@ -187,7 +189,7 @@ public static class AwsEc2AuthenticationOptionsBuilder {
187189

188190
private URI metadataTokenRequestUri = DEFAULT_IMDSV2_TOKEN_URI;
189191

190-
private InstanceMetadataServiceVersion version = InstanceMetadataServiceVersion.V1;
192+
private InstanceMetadataServiceVersion version = InstanceMetadataServiceVersion.V2;
191193

192194
AwsEc2AuthenticationOptionsBuilder() {
193195
}

spring-vault-core/src/test/java/org/springframework/vault/authentication/AwsEc2AuthenticationUnitTests.java

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.springframework.test.web.servlet.MockMvc;
3737
import org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder;
3838
import org.springframework.vault.VaultException;
39+
import org.springframework.vault.authentication.AwsEc2AuthenticationOptions.InstanceMetadataServiceVersion;
3940
import org.springframework.vault.authentication.AwsEc2AuthenticationOptions.Nonce;
4041
import org.springframework.vault.client.VaultClients;
4142
import org.springframework.vault.support.VaultToken;
@@ -69,23 +70,23 @@ void before() {
6970
}
7071

7172
@Test
72-
void shouldObtainIdentityDocument() {
73+
void shouldObtainIdentityDocumentV1() {
74+
75+
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder()
76+
.version(InstanceMetadataServiceVersion.V1)
77+
.build();
7378

7479
this.mockRest.expect(requestTo("http://169.254.169.254/latest/dynamic/instance-identity/pkcs7")) //
7580
.andExpect(method(HttpMethod.GET)) //
7681
.andRespond(withSuccess().body("Hello, world"));
7782

78-
AwsEc2Authentication authentication = new AwsEc2Authentication(this.restTemplate);
83+
AwsEc2Authentication authentication = new AwsEc2Authentication(options, this.restTemplate, this.restTemplate);
7984

8085
assertThat(authentication.getEc2Login()).containsEntry("pkcs7", "Hello, world").containsKey("nonce").hasSize(2);
8186
}
8287

8388
@Test
84-
void shouldObtainIdentityDocumentV2() {
85-
86-
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder()
87-
.version(AwsEc2AuthenticationOptions.InstanceMetadataServiceVersion.V2)
88-
.build();
89+
void shouldObtainIdentityDocument() {
8990

9091
this.mockRest.expect(requestTo("http://169.254.169.254/latest/api/token")) //
9192
.andExpect(method(HttpMethod.PUT)) //
@@ -97,7 +98,7 @@ void shouldObtainIdentityDocumentV2() {
9798
.andExpect(header("X-aws-ec2-metadata-token", "my-token")) //
9899
.andRespond(withSuccess().body("Hello, world"));
99100

100-
AwsEc2Authentication authentication = new AwsEc2Authentication(options, this.restTemplate, this.restTemplate);
101+
AwsEc2Authentication authentication = new AwsEc2Authentication(this.restTemplate);
101102

102103
assertThat(authentication.getEc2Login()).containsEntry("pkcs7", "Hello, world").containsKey("nonce").hasSize(2);
103104
}
@@ -106,7 +107,7 @@ void shouldObtainIdentityDocumentV2() {
106107
void shouldObtainIdentityDocumentWithImperativeAuthenticationStepsV2() {
107108

108109
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder()
109-
.version(AwsEc2AuthenticationOptions.InstanceMetadataServiceVersion.V2)
110+
.version(InstanceMetadataServiceVersion.V2)
110111
.build();
111112

112113
this.mockRest.expect(requestTo("http://169.254.169.254/latest/api/token")) //
@@ -134,19 +135,26 @@ void shouldObtainIdentityDocumentWithImperativeAuthenticationStepsV2() {
134135
@Test
135136
void shouldCleanUpIdentityResponse() {
136137

138+
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder()
139+
.version(InstanceMetadataServiceVersion.V1)
140+
.build();
141+
137142
this.mockRest.expect(requestTo("http://169.254.169.254/latest/dynamic/instance-identity/pkcs7")) //
138143
.andExpect(method(HttpMethod.GET)) //
139144
.andRespond(withSuccess().body("Hello, \r\r\n\nworld"));
140145

141-
AwsEc2Authentication authentication = new AwsEc2Authentication(this.restTemplate);
146+
AwsEc2Authentication authentication = new AwsEc2Authentication(options, this.restTemplate, this.restTemplate);
142147

143148
assertThat(authentication.getEc2Login()).containsEntry("pkcs7", "Hello, world");
144149
}
145150

146151
@Test
147152
void shouldContainRole() {
148153

149-
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder().role("ami").build();
154+
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder()
155+
.role("ami")
156+
.version(InstanceMetadataServiceVersion.V1)
157+
.build();
150158

151159
this.mockRest.expect(requestTo("http://169.254.169.254/latest/dynamic/instance-identity/pkcs7")) //
152160
.andExpect(method(HttpMethod.GET)) //
@@ -166,7 +174,10 @@ void shouldLogin() {
166174

167175
Nonce nonce = Nonce.provided("foo".toCharArray());
168176

169-
AwsEc2AuthenticationOptions authenticationOptions = AwsEc2AuthenticationOptions.builder().nonce(nonce).build();
177+
AwsEc2AuthenticationOptions authenticationOptions = AwsEc2AuthenticationOptions.builder()
178+
.nonce(nonce)
179+
.version(InstanceMetadataServiceVersion.V1)
180+
.build();
170181

171182
this.mockRest.expect(requestTo("http://169.254.169.254/latest/dynamic/instance-identity/pkcs7")) //
172183
.andExpect(method(HttpMethod.GET)) //
@@ -195,7 +206,10 @@ void authenticationChainShouldLogin() {
195206

196207
Nonce nonce = Nonce.provided("foo".toCharArray());
197208

198-
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder().nonce(nonce).build();
209+
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder()
210+
.nonce(nonce)
211+
.version(InstanceMetadataServiceVersion.V1)
212+
.build();
199213

200214
this.mockRest.expect(requestTo("http://169.254.169.254/latest/dynamic/instance-identity/pkcs7")) //
201215
.andExpect(method(HttpMethod.GET)) //
@@ -221,25 +235,34 @@ void authenticationChainShouldLogin() {
221235
@Test
222236
void loginShouldFailWhileObtainingIdentityDocument() {
223237

238+
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder()
239+
.version(InstanceMetadataServiceVersion.V1)
240+
.build();
241+
224242
this.mockRest.expect(requestTo("http://169.254.169.254/latest/dynamic/instance-identity/pkcs7")) //
225243
.andRespond(withServerError());
226244

227245
assertThatExceptionOfType(VaultException.class)
228-
.isThrownBy(() -> new AwsEc2Authentication(this.restTemplate).login());
246+
.isThrownBy(() -> new AwsEc2Authentication(options, this.restTemplate, this.restTemplate).login());
229247
}
230248

231249
@Test
232250
void loginShouldFail() {
233251

252+
AwsEc2AuthenticationOptions options = AwsEc2AuthenticationOptions.builder()
253+
.version(InstanceMetadataServiceVersion.V1)
254+
.build();
255+
234256
this.mockRest.expect(requestTo("/auth/aws-ec2/login")) //
235257
.andRespond(withServerError());
236258

237-
assertThatExceptionOfType(VaultException.class).isThrownBy(() -> new AwsEc2Authentication(this.restTemplate) {
238-
@Override
239-
protected Map<String, String> getEc2Login() {
240-
return Collections.singletonMap("pkcs7", "value");
241-
}
242-
}.login());
259+
assertThatExceptionOfType(VaultException.class)
260+
.isThrownBy(() -> new AwsEc2Authentication(options, this.restTemplate, this.restTemplate) {
261+
@Override
262+
protected Map<String, String> getEc2Login() {
263+
return Collections.singletonMap("pkcs7", "value");
264+
}
265+
}.login());
243266
}
244267

245268
}

0 commit comments

Comments
 (0)