Skip to content

Commit

Permalink
credentials/ssocreds: Add SSOTokenProvider for Bearer Token auth (#1818)
Browse files Browse the repository at this point in the history
Adds a new credential provider, SSOTokenProvider for using Bearer token authentication with AWS services.
  • Loading branch information
jasdel committed Aug 26, 2022
1 parent 8e755b4 commit 1609fe8
Show file tree
Hide file tree
Showing 741 changed files with 2,911 additions and 1,408 deletions.
28 changes: 20 additions & 8 deletions Makefile
Expand Up @@ -72,22 +72,22 @@ all: generate unit
# Code Generation #
###################
.PHONY: generate smithy-generate smithy-build smithy-build-% smithy-clean smithy-go-publish-local format \
gen-config-asserts gen-repo-mod-replace gen-mod-replace-smithy gen-mod-dropreplace-smithy gen-aws-ptrs tidy-modules-% \
gen-config-asserts gen-repo-mod-replace gen-mod-replace-smithy gen-mod-dropreplace-smithy-% gen-aws-ptrs tidy-modules-% \
add-module-license-files sync-models sync-endpoints-model sync-endpoints.json clone-v1-models gen-internal-codegen \
sync-api-models copy-attributevalue-feature min-go-version-% update-requires smithy-annotate-stable \
update-module-metadata download-modules-%

generate: smithy-generate update-requires gen-repo-mod-replace update-module-metadata smithy-annotate-stable \
gen-config-asserts gen-internal-codegen copy-attributevalue-feature gen-mod-dropreplace-smithy min-go-version-. \
gen-config-asserts gen-internal-codegen copy-attributevalue-feature gen-mod-dropreplace-smithy-. min-go-version-. \
tidy-modules-. add-module-license-files gen-aws-ptrs format

smithy-generate:
cd codegen && ./gradlew clean build -Plog-tests && ./gradlew clean

smithy-build: gen-repo-mod-replace
smithy-build:
cd codegen && ./gradlew clean build -Plog-tests

smithy-build-%: gen-repo-mod-replace
smithy-build-%:
@# smithy-build- command that uses the pattern to define build filter that
@# the smithy API model service id starts with. Strips off the
@# "smithy-build-".
Expand Down Expand Up @@ -126,13 +126,25 @@ gen-repo-mod-replace:
@echo "Generating go.mod replace for repo modules"
go run ${REPOTOOLS_CMD_MAKE_RELATIVE}

gen-mod-replace-smithy:
gen-mod-replace-smithy-%:
@# gen-mod-replace-smithy- command that uses the pattern to define build filter that
@# for modules to add replace to. Strips off the "gen-mod-replace-smithy-".
@#
@# SMITHY_GO_SRC environment variable is the path to add replace to
@#
@# e.g. gen-mod-replace-smithy-service_ssooidc
cd ./internal/repotools/cmd/eachmodule \
&& go run . "go mod edit -replace github.com/aws/smithy-go=${SMITHY_GO_SRC}"
&& go run . -p $(subst _,/,$(subst gen-mod-replace-smithy-,,$@)) ${EACHMODULE_FLAGS} \
"go mod edit -replace github.com/aws/smithy-go=${SMITHY_GO_SRC}"

gen-mod-dropreplace-smithy:
gen-mod-dropreplace-smithy-%:
@# gen-mod-dropreplace-smithy- command that uses the pattern to define build filter that
@# for modules to add replace to. Strips off the "gen-mod-dropreplace-smithy-".
@#
@# e.g. gen-mod-dropreplace-smithy-service_ssooidc
cd ./internal/repotools/cmd/eachmodule \
&& go run . "go mod edit -dropreplace github.com/aws/smithy-go"
&& go run . -p $(subst _,/,$(subst gen-mod-dropreplace-smithy-,,$@)) ${EACHMODULE_FLAGS} \
"go mod edit -dropreplace github.com/aws/smithy-go"

gen-aws-ptrs:
cd aws && go generate
Expand Down
15 changes: 14 additions & 1 deletion aws/config.go
Expand Up @@ -3,13 +3,14 @@ package aws
import (
"net/http"

smithybearer "github.com/aws/smithy-go/auth/bearer"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/middleware"
)

// HTTPClient provides the interface to provide custom HTTPClients. Generally
// *http.Client is sufficient for most use cases. The HTTPClient should not
// follow redirects.
// follow 301 or 302 redirects.
type HTTPClient interface {
Do(*http.Request) (*http.Response, error)
}
Expand All @@ -30,6 +31,18 @@ type Config struct {
// variables, shared credential file, and EC2 Instance Roles.
Credentials CredentialsProvider

// The Bearer Authentication token provider to use for authenticating API
// operation calls with a Bearer Authentication token. The API clients and
// operation must support Bearer Authentication scheme in order for the
// token provider to be used. API clients created with NewFromConfig will
// automatically be configured with this option, if the API client support
// Bearer Authentication.
//
// The SDK's config.LoadDefaultConfig can automatically populate this
// option for external configuration options such as SSO session.
// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
BearerAuthTokenProvider smithybearer.TokenProvider

// The HTTP Client the SDK's API clients will use to invoke HTTP requests.
// The SDK defaults to a BuildableClient allowing API clients to create
// copies of the HTTP Client for service specific customizations.
Expand Down
2 changes: 1 addition & 1 deletion aws/protocol/eventstream/go.mod
Expand Up @@ -2,6 +2,6 @@ module github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream

go 1.15

require github.com/aws/smithy-go v1.12.1
require github.com/aws/smithy-go v1.12.2-0.20220825202034-eec4392b3806

replace github.com/aws/aws-sdk-go-v2 => ../../../
4 changes: 2 additions & 2 deletions aws/protocol/eventstream/go.sum
@@ -1,5 +1,5 @@
github.com/aws/smithy-go v1.12.1 h1:yQRC55aXN/y1W10HgwHle01DRuV9Dpf31iGkotjt3Ag=
github.com/aws/smithy-go v1.12.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/aws/smithy-go v1.12.2-0.20220825202034-eec4392b3806 h1:txHpJGVo/VYIWocLOG23AI791W9xLhh4z9NrG51Xd8k=
github.com/aws/smithy-go v1.12.2-0.20220825202034-eec4392b3806/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
Expand Down
2 changes: 1 addition & 1 deletion aws/signer/v4/middleware.go
Expand Up @@ -82,7 +82,7 @@ func (m *dynamicPayloadSigningMiddleware) HandleBuild(
}

// if TLS is enabled, use unsigned payload when supported
if strings.EqualFold(req.URL.Scheme, "https") {
if req.IsHTTPS() {
return (&unsignedPayload{}).HandleBuild(ctx, in, next)
}

Expand Down
Expand Up @@ -23,10 +23,8 @@
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.logging.Logger;

import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.codegen.core.SymbolProvider;
import software.amazon.smithy.aws.go.codegen.ClientResolvedDefaultsMode;
import software.amazon.smithy.go.codegen.GoDelegator;
import software.amazon.smithy.go.codegen.GoSettings;
import software.amazon.smithy.go.codegen.GoWriter;
Expand All @@ -36,6 +34,7 @@
import software.amazon.smithy.go.codegen.integration.ConfigFieldResolver;
import software.amazon.smithy.go.codegen.integration.GoIntegration;
import software.amazon.smithy.go.codegen.integration.RuntimeClientPlugin;
import software.amazon.smithy.go.codegen.integration.auth.HttpBearerAuth;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.utils.ListUtils;
Expand All @@ -48,6 +47,7 @@ public class AddAwsConfigFields implements GoIntegration {

public static final String REGION_CONFIG_NAME = "Region";
public static final String CREDENTIALS_CONFIG_NAME = "Credentials";
public static final String BEARER_AUTH_TOKEN_CONFIG_NAME = "TokenProvider";
public static final String ENDPOINT_RESOLVER_CONFIG_NAME = "EndpointResolver";
public static final String AWS_ENDPOINT_RESOLVER_WITH_OPTIONS = "EndpointResolverWithOptions";
public static final String HTTP_CLIENT_CONFIG_NAME = "HTTPClient";
Expand Down Expand Up @@ -120,20 +120,20 @@ public class AddAwsConfigFields implements GoIntegration {
When creating a new API Clients this member will only be used if the
Retryer Options member is nil. This value will be ignored if
Retryer is not nil.
If specified in an operation call's functional options with a value that
is different than the constructed client's Options, the Client's Retryer
will be wrapped to use the operation's specific RetryMaxAttempts value.
""")
.awsResolveFunction(SymbolUtils.createValueSymbolBuilder(RESOLVE_AWS_CONFIG_RETRY_MAX_ATTEMPTS)
.build())
.addConfigFieldResolvers(ConfigFieldResolver.builder()
.location(ConfigFieldResolver.Location.OPERATION)
.target(ConfigFieldResolver.Target.FINALIZATION)
.withClientInput(true)
.resolver(SymbolUtils.createValueSymbolBuilder(
FINALIZE_RETRY_MAX_ATTEMPTS_OPTIONS).build())
.build())
.addConfigFieldResolvers(ConfigFieldResolver.builder()
.location(ConfigFieldResolver.Location.OPERATION)
.target(ConfigFieldResolver.Target.FINALIZATION)
.withClientInput(true)
.resolver(SymbolUtils.createValueSymbolBuilder(
FINALIZE_RETRY_MAX_ATTEMPTS_OPTIONS).build())
.build())
.build(),

AwsConfigField.builder()
Expand All @@ -146,7 +146,7 @@ public class AddAwsConfigFields implements GoIntegration {
When creating a new API Clients this member will only be used if the
Retryer Options member is nil. This value will be ignored if
Retryer is not nil.
Currently does not support per operation call overrides, may in the future.
""")
.awsResolveFunction(SymbolUtils.createValueSymbolBuilder(RESOLVE_AWS_CONFIG_RETRY_MODE)
Expand All @@ -166,6 +166,16 @@ public class AddAwsConfigFields implements GoIntegration {
.documentation("The credentials object to use when signing requests.")
.servicePredicate(AwsSignatureVersion4::isSupportedAuthentication)
.build(),
AwsConfigField.builder()
// TOKEN_PROVIDER_OPTION_NAME added API Client's Options by HttpBearerAuth. Only
// need to add NewFromConfig resolver from aws#Config type.
.name(HttpBearerAuth.TOKEN_PROVIDER_OPTION_NAME)
.type(SymbolUtils.createValueSymbolBuilder("TokenProvider",
SmithyGoDependency.SMITHY_AUTH_BEARER).build())
.documentation("The bearer authentication token provider for authentication requests.")
.servicePredicate(HttpBearerAuth::isSupportedAuthentication)
.generatedOnClient(false)
.build(),
AwsConfigField.builder()
.name(API_OPTIONS_CONFIG_NAME)
.type(SymbolUtils.createValueSymbolBuilder("[]func(*middleware.Stack) error")
Expand Down
3 changes: 3 additions & 0 deletions config/codegen/main.go
Expand Up @@ -27,6 +27,9 @@ var implAsserts = map[string][]string{
"credentialsProviderProvider": {loadOptionsType},
"defaultRegionProvider": {loadOptionsType},
"credentialsCacheOptionsProvider": {loadOptionsType},
"bearerAuthTokenProviderProvider": {loadOptionsType},
"bearerAuthTokenCacheOptionsProvider": {loadOptionsType},
"ssoTokenProviderOptionsProvider": {loadOptionsType},
"processCredentialOptions": {loadOptionsType},
"ec2RoleCredentialOptionsProvider": {loadOptionsType},
"endpointCredentialOptionsProvider": {loadOptionsType},
Expand Down
4 changes: 4 additions & 0 deletions config/config.go
Expand Up @@ -72,6 +72,10 @@ var defaultAWSConfigResolvers = []awsConfigResolver{
// implementations depend on or can be configured with earlier resolved
// configuration options.
resolveCredentials,

// Sets the resolved bearer authentication token API clients will use for
// httpBearerAuth authentication scheme.
resolveBearerAuthToken,
}

// A Config represents a generic configuration value or set of values. This type
Expand Down
5 changes: 4 additions & 1 deletion config/go.mod
Expand Up @@ -8,8 +8,9 @@ require (
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19
github.com/aws/aws-sdk-go-v2/service/sso v1.11.17
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.0
github.com/aws/aws-sdk-go-v2/service/sts v1.16.13
github.com/aws/smithy-go v1.12.1
github.com/aws/smithy-go v1.12.2-0.20220825202034-eec4392b3806
github.com/google/go-cmp v0.5.8
)

Expand All @@ -29,4 +30,6 @@ replace github.com/aws/aws-sdk-go-v2/service/internal/presigned-url => ../servic

replace github.com/aws/aws-sdk-go-v2/service/sso => ../service/sso/

replace github.com/aws/aws-sdk-go-v2/service/ssooidc => ../service/ssooidc/

replace github.com/aws/aws-sdk-go-v2/service/sts => ../service/sts/
4 changes: 2 additions & 2 deletions config/go.sum
@@ -1,5 +1,5 @@
github.com/aws/smithy-go v1.12.1 h1:yQRC55aXN/y1W10HgwHle01DRuV9Dpf31iGkotjt3Ag=
github.com/aws/smithy-go v1.12.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/aws/smithy-go v1.12.2-0.20220825202034-eec4392b3806 h1:txHpJGVo/VYIWocLOG23AI791W9xLhh4z9NrG51Xd8k=
github.com/aws/smithy-go v1.12.2-0.20220825202034-eec4392b3806/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
Expand Down
79 changes: 79 additions & 0 deletions config/load_options.go
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
smithybearer "github.com/aws/smithy-go/auth/bearer"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/middleware"
)
Expand All @@ -28,6 +29,9 @@ type LoadOptions struct {
// Credentials object to use when signing requests.
Credentials aws.CredentialsProvider

// Token provider for authentication operations with bearer authentication.
BearerAuthTokenProvider smithybearer.TokenProvider

// HTTPClient the SDK's API clients will use to invoke HTTP requests.
HTTPClient HTTPClient

Expand Down Expand Up @@ -128,6 +132,14 @@ type LoadOptions struct {
// aws.CredentialsCacheOptions
CredentialsCacheOptions func(*aws.CredentialsCacheOptions)

// BearerAuthTokenCacheOptions is a function for setting the smithy-go
// auth/bearer#TokenCacheOptions
BearerAuthTokenCacheOptions func(*smithybearer.TokenCacheOptions)

// SSOTokenProviderOptions is a function for setting the
// credentials/ssocreds.SSOTokenProviderOptions
SSOTokenProviderOptions func(*ssocreds.SSOTokenProviderOptions)

// ProcessCredentialOptions is a function for setting
// the processcreds.Options
ProcessCredentialOptions func(*processcreds.Options)
Expand Down Expand Up @@ -451,6 +463,73 @@ func WithCredentialsCacheOptions(v func(*aws.CredentialsCacheOptions)) LoadOptio
}
}

// getBearerAuthTokenProvider returns the credentials value
func (o LoadOptions) getBearerAuthTokenProvider(ctx context.Context) (smithybearer.TokenProvider, bool, error) {
if o.BearerAuthTokenProvider == nil {
return nil, false, nil
}

return o.BearerAuthTokenProvider, true, nil
}

// WithBearerAuthTokenProvider is a helper function to construct functional options
// that sets Credential provider value on config's LoadOptions. If credentials
// provider is set to nil, the credentials provider value will be ignored.
// If multiple WithBearerAuthTokenProvider calls are made, the last call overrides
// the previous call values.
func WithBearerAuthTokenProvider(v smithybearer.TokenProvider) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.BearerAuthTokenProvider = v
return nil
}
}

// getBearerAuthTokenCacheOptionsProvider returns the wrapped function to set smithybearer.TokenCacheOptions
func (o LoadOptions) getBearerAuthTokenCacheOptions(ctx context.Context) (func(*smithybearer.TokenCacheOptions), bool, error) {
if o.BearerAuthTokenCacheOptions == nil {
return nil, false, nil
}

return o.BearerAuthTokenCacheOptions, true, nil
}

// WithBearerAuthTokenCacheOptions is a helper function to construct functional options
// that sets a function to modify the TokenCacheOptions the smithy-go
// auth/bearer#TokenCache will be configured with, if the TokenCache is used by
// the configuration loader.
//
// If multiple WithBearerAuthTokenCacheOptions calls are made, the last call overrides
// the previous call values.
func WithBearerAuthTokenCacheOptions(v func(*smithybearer.TokenCacheOptions)) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.BearerAuthTokenCacheOptions = v
return nil
}
}

// getSSOTokenProviderOptionsProvider returns the wrapped function to set smithybearer.TokenCacheOptions
func (o LoadOptions) getSSOTokenProviderOptions(ctx context.Context) (func(*ssocreds.SSOTokenProviderOptions), bool, error) {
if o.SSOTokenProviderOptions == nil {
return nil, false, nil
}

return o.SSOTokenProviderOptions, true, nil
}

// WithSSOTokenProviderOptions is a helper function to construct functional
// options that sets a function to modify the SSOtokenProviderOptions the SDK's
// credentials/ssocreds#SSOProvider will be configured with, if the
// SSOTokenProvider is used by the configuration loader.
//
// If multiple WithSSOTokenProviderOptions calls are made, the last call overrides
// the previous call values.
func WithSSOTokenProviderOptions(v func(*ssocreds.SSOTokenProviderOptions)) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.SSOTokenProviderOptions = v
return nil
}
}

// getProcessCredentialOptions returns the wrapped function to set processcreds.Options
func (o LoadOptions) getProcessCredentialOptions(ctx context.Context) (func(*processcreds.Options), bool, error) {
if o.ProcessCredentialOptions == nil {
Expand Down

0 comments on commit 1609fe8

Please sign in to comment.