-
Notifications
You must be signed in to change notification settings - Fork 597
/
resolve_bearer_token.go
123 lines (102 loc) · 3.8 KB
/
resolve_bearer_token.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package config
import (
"context"
"fmt"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
"github.com/aws/aws-sdk-go-v2/service/ssooidc"
smithybearer "github.com/aws/smithy-go/auth/bearer"
)
// resolveBearerAuthToken extracts a token provider from the config sources.
//
// If an explicit bearer authentication token provider is not found the
// resolver will fallback to resolving token provider via other config sources
// such as SharedConfig.
func resolveBearerAuthToken(ctx context.Context, cfg *aws.Config, configs configs) error {
found, err := resolveBearerAuthTokenProvider(ctx, cfg, configs)
if found || err != nil {
return err
}
return resolveBearerAuthTokenProviderChain(ctx, cfg, configs)
}
// resolveBearerAuthTokenProvider extracts the first instance of
// BearerAuthTokenProvider from the config sources.
//
// The resolved BearerAuthTokenProvider will be wrapped in a cache to ensure
// the Token is only refreshed when needed. This also protects the
// TokenProvider so it can be used concurrently.
//
// Config providers used:
// * bearerAuthTokenProviderProvider
func resolveBearerAuthTokenProvider(ctx context.Context, cfg *aws.Config, configs configs) (bool, error) {
tokenProvider, found, err := getBearerAuthTokenProvider(ctx, configs)
if !found || err != nil {
return false, err
}
cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache(
ctx, configs, tokenProvider)
if err != nil {
return false, err
}
return true, nil
}
func resolveBearerAuthTokenProviderChain(ctx context.Context, cfg *aws.Config, configs configs) (err error) {
_, sharedConfig, _ := getAWSConfigSources(configs)
if len(sharedConfig.SSOSessionName) == 0 || sharedConfig.SSOSession == nil {
err = fmt.Errorf("both sso_session name and sso-session section must be set, %w", err)
return err
}
provider, err := resolveBearerAuthSSOTokenProvider(
ctx, cfg, sharedConfig.SSOSession, configs)
if err == nil && provider != nil {
cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache(
ctx, configs, provider)
}
return err
}
func resolveBearerAuthSSOTokenProvider(ctx context.Context, cfg *aws.Config, session *SSOSession, configs configs) (*ssocreds.SSOTokenProvider, error) {
ssoTokenProviderOptionsFn, found, err := getSSOTokenProviderOptions(ctx, configs)
if err != nil {
return nil, fmt.Errorf("failed to get SSOTokenProviderOptions from config sources, %w", err)
}
var optFns []func(*ssocreds.SSOTokenProviderOptions)
if found {
optFns = append(optFns, ssoTokenProviderOptionsFn)
}
cachePath, err := ssocreds.StandardCachedTokenFilepath(session.Name)
if err != nil {
return nil, fmt.Errorf("failed to get SSOTokenProvider's cache path, %w", err)
}
client := ssooidc.NewFromConfig(*cfg)
provider := ssocreds.NewSSOTokenProvider(client, cachePath, optFns...)
return provider, nil
}
// wrapWithBearerAuthTokenCache will wrap provider with an smithy-go
// bearer/auth#TokenCache with the provided options if the provider is not
// already a TokenCache.
func wrapWithBearerAuthTokenCache(
ctx context.Context,
cfgs configs,
provider smithybearer.TokenProvider,
optFns ...func(*smithybearer.TokenCacheOptions),
) (smithybearer.TokenProvider, error) {
_, ok := provider.(*smithybearer.TokenCache)
if ok {
return provider, nil
}
tokenCacheConfigOptions, optionsFound, err := getBearerAuthTokenCacheOptions(ctx, cfgs)
if err != nil {
return nil, err
}
opts := make([]func(*smithybearer.TokenCacheOptions), 0, 2+len(optFns))
opts = append(opts, func(o *smithybearer.TokenCacheOptions) {
o.RefreshBeforeExpires = 5 * time.Minute
o.RetrieveBearerTokenTimeout = 30 * time.Second
})
opts = append(opts, optFns...)
if optionsFound {
opts = append(opts, tokenCacheConfigOptions)
}
return smithybearer.NewTokenCache(provider, opts...), nil
}