File: resolve_bearer_token.go

package info (click to toggle)
golang-github-aws-aws-sdk-go-v2 1.17.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 384,244 kB
  • sloc: java: 13,538; makefile: 400; sh: 137
file content (133 lines) | stat: -rw-r--r-- 4,175 bytes parent folder | download
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
124
125
126
127
128
129
130
131
132
133
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)

	var provider smithybearer.TokenProvider

	if sharedConfig.SSOSession != nil || (sharedConfig.SSORegion != "" && sharedConfig.SSOStartURL != "") {
		ssoSession := sharedConfig.SSOSession
		if ssoSession == nil {
			// Fallback to legacy SSO session config parameters, if the
			// sso-session section wasn't used.
			ssoSession = &SSOSession{
				Name:        sharedConfig.SSOStartURL,
				SSORegion:   sharedConfig.SSORegion,
				SSOStartURL: sharedConfig.SSOStartURL,
			}
		}

		provider, err = resolveBearerAuthSSOTokenProvider(
			ctx, cfg, 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
}