12
12
*/
13
13
package io .kubernetes .client .util .credentials ;
14
14
15
- import com .amazonaws .DefaultRequest ;
16
- import com .amazonaws .auth .AWS4Signer ;
17
- import com .amazonaws .auth .AWSSessionCredentialsProvider ;
18
- import com .amazonaws .http .HttpMethodName ;
19
- import com .amazonaws .services .securitytoken .model .GetCallerIdentityRequest ;
20
- import com .amazonaws .util .RuntimeHttpUtils ;
21
15
import io .kubernetes .client .openapi .ApiClient ;
22
16
import org .slf4j .Logger ;
23
17
import org .slf4j .LoggerFactory ;
18
+ import software .amazon .awssdk .auth .credentials .AwsCredentialsProvider ;
19
+ import software .amazon .awssdk .http .SdkHttpMethod ;
20
+ import software .amazon .awssdk .http .SdkHttpRequest ;
21
+ import software .amazon .awssdk .http .auth .aws .signer .AwsV4FamilyHttpSigner ;
22
+ import software .amazon .awssdk .http .auth .aws .signer .AwsV4HttpSigner ;
23
+ import software .amazon .awssdk .http .auth .spi .signer .SignedRequest ;
24
+ import software .amazon .awssdk .utils .http .SdkHttpUtils ;
24
25
25
26
import java .net .URI ;
26
27
import java .nio .charset .StandardCharsets ;
27
- import java .time .Clock ;
28
+ import java .time .Duration ;
28
29
import java .time .Instant ;
29
30
import java .time .temporal .ChronoUnit ;
30
31
import java .util .Base64 ;
31
- import java .util .Date ;
32
32
33
33
/**
34
34
* EKS cluster authentication which generates a bearer token from AWS AK/SK. It doesn't require an "aws"
@@ -45,11 +45,11 @@ public class EKSAuthentication implements Authentication {
45
45
* @param region the region where EKS cluster at
46
46
* @param clusterName the EKS cluster name
47
47
*/
48
- public EKSAuthentication (AWSSessionCredentialsProvider provider , String region , String clusterName ) {
48
+ public EKSAuthentication (AwsCredentialsProvider provider , String region , String clusterName ) {
49
49
this (provider , region , clusterName , MAX_EXPIRY_SECONDS );
50
50
}
51
51
52
- public EKSAuthentication (AWSSessionCredentialsProvider provider , String region , String clusterName , int expirySeconds ) {
52
+ public EKSAuthentication (AwsCredentialsProvider provider , String region , String clusterName , int expirySeconds ) {
53
53
this .provider = provider ;
54
54
this .region = region ;
55
55
this .clusterName = clusterName ;
@@ -61,7 +61,7 @@ public EKSAuthentication(AWSSessionCredentialsProvider provider, String region,
61
61
}
62
62
63
63
private static final int MAX_EXPIRY_SECONDS = 60 * 15 ;
64
- private final AWSSessionCredentialsProvider provider ;
64
+ private final AwsCredentialsProvider provider ;
65
65
private final String region ;
66
66
private final String clusterName ;
67
67
private final URI stsEndpoint ;
@@ -70,30 +70,41 @@ public EKSAuthentication(AWSSessionCredentialsProvider provider, String region,
70
70
71
71
@ Override
72
72
public void provide (ApiClient client ) {
73
- DefaultRequest <GetCallerIdentityRequest > defaultRequest =
74
- new DefaultRequest <>(new GetCallerIdentityRequest (), "sts" );
75
- defaultRequest .setResourcePath ("/" );
76
- defaultRequest .setEndpoint (stsEndpoint );
77
- defaultRequest .setHttpMethod (HttpMethodName .GET );
78
- defaultRequest .addParameter ("Action" , "GetCallerIdentity" );
79
- defaultRequest .addParameter ("Version" , "2011-06-15" );
80
- defaultRequest .addHeader ("x-k8s-aws-id" , clusterName );
81
- AWS4Signer signer = new AWS4Signer ();
82
- Date expirationTime = new Date (Clock .systemDefaultZone ().millis () + 60 * 1000 );
83
- signer .setServiceName ("sts" );
84
- signer .presignRequest (
85
- defaultRequest ,
86
- this .provider .getCredentials (),
87
- expirationTime );
88
- String encodedUrl =
89
- Base64 .getUrlEncoder ()
90
- .withoutPadding ()
91
- .encodeToString ( RuntimeHttpUtils .convertRequestToUrl (
92
- defaultRequest , true , false ).toString ()
93
- .getBytes (StandardCharsets .UTF_8 ));
73
+ SdkHttpRequest httpRequest = generateStsRequest ();
74
+ String presignedUrl = requestToPresignedUrl (httpRequest );
75
+ String encodedUrl = presignedUrlToEncodedUrl (presignedUrl );
94
76
String token = "k8s-aws-v1." + encodedUrl ;
95
77
client .setApiKeyPrefix ("Bearer" );
96
78
client .setApiKey (token );
97
79
log .info ("Generated BEARER token for ApiClient, expiring at {}" , Instant .now ().plus (expirySeconds , ChronoUnit .SECONDS ));
98
80
}
81
+
82
+ private static String presignedUrlToEncodedUrl (String presignedUrl ) {
83
+ return Base64 .getUrlEncoder ()
84
+ .withoutPadding ()
85
+ .encodeToString (SdkHttpUtils .urlEncodeIgnoreSlashes (presignedUrl ).getBytes (StandardCharsets .UTF_8 ));
86
+ }
87
+
88
+ private SdkHttpRequest generateStsRequest () {
89
+ return SdkHttpRequest .builder ()
90
+ .uri (stsEndpoint )
91
+ .putRawQueryParameter ("Version" , "2011-06-15" )
92
+ .putRawQueryParameter ("Action" , "GetCallerIdentity" )
93
+ .method (SdkHttpMethod .GET )
94
+ .putHeader ("x-k8s-aws-id" , clusterName )
95
+ .build ();
96
+ }
97
+
98
+ private String requestToPresignedUrl (SdkHttpRequest httpRequest ) {
99
+ AwsV4HttpSigner signer = AwsV4HttpSigner .create ();
100
+ SignedRequest signedRequest =
101
+ signer .sign (r -> r .identity (this .provider .resolveCredentials ())
102
+ .request (httpRequest )
103
+ .putProperty (AwsV4HttpSigner .SERVICE_SIGNING_NAME , "sts" )
104
+ .putProperty (AwsV4HttpSigner .REGION_NAME , region )
105
+ .putProperty (AwsV4HttpSigner .AUTH_LOCATION , AwsV4HttpSigner .AuthLocation .QUERY_STRING )
106
+ .putProperty (AwsV4HttpSigner .EXPIRATION_DURATION , Duration .of (60 , ChronoUnit .SECONDS )));
107
+ SdkHttpRequest request = signedRequest .request ();
108
+ return request .getUri ().toString ();
109
+ }
99
110
}
0 commit comments