Name Date Size #Lines LOC

..--

README.mdH A D25-Apr-20257.4 KiB199150

README.md

1**Design:** New Feature, **Status:** [Released](../../../README.md)
2
3# Bearer Token Authorization and Token Providers
4
5**What is Bearer Token authorization?**
6
7Bearer Token authorization is a method used to authenticate service request using
8[Bearer Token](https://oauth.net/2/bearer-tokens/) instead of traditional AWS credentials .This is performed by
9populating authorization header with bearer token.
10
11**What is the user experience?**
12
13First, users will be able to configure a profile in the shared SDK configuration files that allows them to
14perform an initial login via the AWS CLI or AWS IDE plugins. For example, this profile might look like this:
15
16 ```
17 [profile sono]
18 sso_start_url = https://sono.aws
19 sso_region = us-east-1
20 ```
21
22With this configuration, a user would be able to login via a supported tool such as the AWS CLI:
23
24 ```
25 $ aws sso login --profile sono
26 ```
27
28Upon completing this login, a cached token will be available under
29`~/.aws/sso/cache` which will be used by the SDK to perform bearer token
30authorization.
31
32The service will be modeled at the service level to use the `bearer`
33signature version. This client would know how to load the cached token based on the
34profile configuration and populate the bearer authorization header using it.
35This is similar to how an SDK would resolve AWS credentials and perform SigV4
36signing.
37
38*Example*
39
40For example, given a token value of `"mF_9.B5f-4.1JqM"` the value of the
41`Authorization` header would be: `"Bearer mF_9.B5f-4.1JqM"`. A full HTTP
42request may look like the following:
43
44 ```
45 GET /resource HTTP/1.1
46 Host: server.example.com
47 Authorization: Bearer mF_9.B5f-4.1JqM
48 ```
49
50## Proposed APIs
51
52When the SDK 2.x client encounters a service or operation that is modeled or configured to use the
53`bearer` signature version, the client will consult the token provider chain to
54derive a token to be used in generating and attaching the authorization to a request.
55
56### API Design for Token/Token Providers and Token Provider Chains
57
58Even though Tokens/TokenProvider and Token Providers is similar to AWS Credentials,
59AWS Credential Provider and AWSCredentialProvider Chain, we will need to provide new interfaces for the following reasons.
60 1. Credentials get finally resolved to accessKeyId and secretAccessKey. These are related to AWS account login.
61 2. SDK should support clients configured for multiple types of credentials (e.g. token and AWS credentials)
62
63#### Token
64
65SDK will support representations of a token that contains additional metadata including the token string and
66the expiration field.
67```java
68@SdkPublicApi
69public interface SdkToken {
70    String token();
71    Optional<Instant> expirationTime();
72}
73
74```
75
76#### Token Provider
77
78To produce a token object SDKs will implement support for token providers and token provider chains.
79The token provider and provider chain interfaces will mirror the existing AWS credential provider
80interfaces in the SDK, but instead return a Token object.
81
82```java
83@FunctionalInterface
84@SdkPublicApi
85public interface SdkTokenProvider {
86
87    SdkToken resolveToken();
88}
89```
90SsoTokenProvider is an implementation of SdkTokenProvider that is capable of loading and  storing SSO tokens to
91`~/.aws/sso/cache`. This is also capable of refreshing the cached token via the SSO-OIDC service.
92
93
94```java
95        SsoTokenProvider ssoTokenProvider =  SsoTokenProvider.builder()
96                               .startUrl("https://d-abc123.awsapps.com/start")
97                               .build();
98```
99
100The StaticTokenProvider represents the simplest possible token provider.
101It simply returns a static token string and has an optional expiration.
102
103```java
104 StaticTokenProvider provider = StaticTokenProvider.create(bearerToken);
105```
106
107#### Token Provider Chains
108
109SdkTokenProviderChain is an implementation of SdkTokenProvider that chains together multiple token providers.
110The public method of this class is exactly same as [AwsCredentialsProviderChain](https://github.com/aws/aws-sdk-java-v2/blob/master/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsCredentialsProviderChain.java)
111except it resolves the Token providers.
112
113#### ClientBuilder API to set Token Privder
114
115A new API will be added in [AwsClientBuilder](https://github.com/aws/aws-sdk-java-v2/blob/master/core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsClientBuilder.java)
116to set the tokenProvider to a client.
117
118```java
119
120   SdkTokenProviderChain TOKEN_PROVIDER_CHAIN =  DefaultSdkTokenProvderChain.create();
121   ServiceClient.builder()
122                 .region(REGION)
123                 .tokenProvider(TOKEN_PROVIDER_CHAIN)
124                 .build();
125```
126
127
128### Bearer Token Authorizer
129
130Bearer Token Authorization will be done by BearerTokenSigner that will update the Authorization header with bearer
131token that is resolved from Token Provider.
132
133```java
134@SdkPublicApi
135public final class BearerTokenSigner implements Signer {
136
137    @Override
138    public CredentialType credentialType() {
139        return CredentialType.TOKEN;
140    }
141
142    @Override
143    public SdkHttpFullRequest sign(SdkHttpFullRequest request, ExecutionAttributes executionAttributes) {
144       /**
145        * doSign will do following
146        * 1. Resolve token from Token Provider
147        * 2. Set the Authorization header by filling in the token to the following format string: "Bearer {token}".
148        */
149        return doSign(request, executionAttributes);
150    }
151    public static BearerTokenSigner create() {
152        return new BearerTokenSigner();
153    }
154}
155
156```
157#### ClientBuilder API to set Bearer Token Signer
158
159A new AdvancedOption setting `BEARER_SIGNER` will be created to add bearer signer
160
161```java
162
163   ServiceClient.builder()
164                   .region(REGION)
165                   .overrideConfiguration(
166                        ClientOverrideConfiguration.builder()
167                                                   .putAdvancedOption(BEARER_SIGNER, DefaultBearerTokenSigner.create())
168                                                   .build())
169                    .build();
170```
171
172Also, ClientBuilder can be updated with Bearer Token Signer by using existing `SIGNER` advancedOption
173```java
174   serviceClient.builder()
175                   .region(REGION)
176                   .overrideConfiguration(
177                        ClientOverrideConfiguration.builder()
178                                                   .putAdvancedOption(SIGNER, DefaultBearerTokenSigner.create())
179                                                   .build())
180```
181#### OperationRequest Builder API to set Bearer Token Signer
182Bearer Token Signer can be set at request level by overriding configuration for request operation.
183A new API `bearerTokenSigner(BearerTokenSigner bearerTokenSigner)` will be added in
184[RequestOverrideConfiguration](https://github.com/aws/aws-sdk-java-v2/blob/master/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.java).
185
186```java
187   serviceClient.operation(OperationRequest.builder()
188                                           .overrideConfiguration(o -> o.bearerTokenSigner(DefaultBearerTokenSigner.create()))
189                                           .build());
190```
191
192Also, BearerTokenSigner can be updated by setting signer on RequestOverrideConfiguration.
193
194```java
195   serviceClient.operation(OperationRequest.builder()
196                                        .overrideConfiguration(o -> o.signer(DefaultBearerTokenSigner.create()))
197                                        .build());
198```
199