Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sra identity&auth refactor #2364

Merged
merged 4 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
8 changes: 8 additions & 0 deletions .changelog/3d28deab28ab4b1389b3eb1441d90b89.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "3d28deab-28ab-4b13-89b3-eb1441d90b89",
"type": "feature",
"description": "**BREAKING CHANGE**: V2 endpoint resolution middleware has changed steps from Serialize to Finalize. Middleware that indexes off of this field will need to be updated accordingly.",
"modules": [
"."
]
}
8 changes: 8 additions & 0 deletions .changelog/4b09f5bca287465e90e598267752b46b.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "4b09f5bc-a287-465e-90e5-98267752b46b",
"type": "feature",
"description": "Add client config helpers for overriding SigV4 signing name and region.",
"modules": [
"."
]
}
8 changes: 8 additions & 0 deletions .changelog/5b1f51867cf64283bb299ade04d2d3d6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "5b1f5186-7cf6-4283-bb29-9ade04d2d3d6",
"type": "feature",
"description": "Support smithy-modeled identity and auth resolution. Service clients can now be configured to override or use additional authentication schemes.",
"modules": [
"."
]
}
8 changes: 8 additions & 0 deletions .changelog/cb8e0d473b92444396bcd34db0cefe86.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "cb8e0d47-3b92-4443-96bc-d34db0cefe86",
"type": "feature",
"description": "**BREAKING CHANGE**: Request body checksum middlewares (flex checksums, SHA256, etc.) have changed steps from Build to Finalize. Middleware that indexes off of this field will need to be updated accordingly.",
"modules": [
"."
]
}
8 changes: 8 additions & 0 deletions .changelog/f074fcf7bb8c43acbe575b407d7efdae.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "f074fcf7-bb8c-43ac-be57-5b407d7efdae",
"type": "feature",
"description": "Refactored endpoint resolution middleware into a single implementation per-service, reducing generated code footprint.",
"modules": [
"."
]
}
8 changes: 8 additions & 0 deletions .changelog/fc9d5a0f6ff64fc8a19eb9711740be6e.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "fc9d5a0f-6ff6-4fc8-a19e-b9711740be6e",
"type": "feature",
"description": "**BREAKING CHANGE**: DisableHTTPS middleware has changed steps from Serialize to Finalize. Middleware that indexes off of this field will need to be updated accordingly.",
"modules": [
"."
]
}
14 changes: 13 additions & 1 deletion aws/middleware/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ func GetServiceID(ctx context.Context) (v string) {
//
// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues
// to clear all stack values.
//
// Deprecated: This value is unstable. The resolved signing name is available
// in the signer properties object passed to the signer.
func GetSigningName(ctx context.Context) (v string) {
v, _ = middleware.GetStackValue(ctx, signingNameKey{}).(string)
return v
Expand All @@ -74,6 +77,9 @@ func GetSigningName(ctx context.Context) (v string) {
//
// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues
// to clear all stack values.
//
// Deprecated: This value is unstable. The resolved signing region is available
// in the signer properties object passed to the signer.
func GetSigningRegion(ctx context.Context) (v string) {
v, _ = middleware.GetStackValue(ctx, signingRegionKey{}).(string)
return v
Expand Down Expand Up @@ -125,10 +131,13 @@ func SetRequiresLegacyEndpoints(ctx context.Context, value bool) context.Context
return middleware.WithStackValue(ctx, requiresLegacyEndpointsKey{}, value)
}

// SetSigningName set or modifies the signing name on the context.
// SetSigningName set or modifies the sigv4 or sigv4a signing name on the context.
//
// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues
// to clear all stack values.
//
// Deprecated: This value is unstable. Use WithSigV4SigningName client option
// funcs instead.
func SetSigningName(ctx context.Context, value string) context.Context {
return middleware.WithStackValue(ctx, signingNameKey{}, value)
}
Expand All @@ -137,6 +146,9 @@ func SetSigningName(ctx context.Context, value string) context.Context {
//
// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues
// to clear all stack values.
//
// Deprecated: This value is unstable. Use WithSigV4SigningRegion client option
// funcs instead.
func SetSigningRegion(ctx context.Context, value string) context.Context {
return middleware.WithStackValue(ctx, signingRegionKey{}, value)
}
Expand Down
95 changes: 41 additions & 54 deletions aws/signer/v4/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (e *SigningError) Unwrap() error {
// S3 PutObject API allows unsigned payload signing auth usage when TLS is enabled, and uses this middleware to
// dynamically switch between unsigned and signed payload based on TLS state for request.
func UseDynamicPayloadSigningMiddleware(stack *middleware.Stack) error {
_, err := stack.Build.Swap(computePayloadHashMiddlewareID, &dynamicPayloadSigningMiddleware{})
_, err := stack.Finalize.Swap(computePayloadHashMiddlewareID, &dynamicPayloadSigningMiddleware{})
return err
}

Expand All @@ -71,24 +71,22 @@ func (m *dynamicPayloadSigningMiddleware) ID() string {
return computePayloadHashMiddlewareID
}

// HandleBuild sets a resolver that directs to the payload sha256 compute handler.
func (m *dynamicPayloadSigningMiddleware) HandleBuild(
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
// HandleFinalize delegates SHA256 computation according to whether the request
// is TLS-enabled.
func (m *dynamicPayloadSigningMiddleware) HandleFinalize(
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
) (
out middleware.BuildOutput, metadata middleware.Metadata, err error,
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
}

// if TLS is enabled, use unsigned payload when supported
if req.IsHTTPS() {
return (&unsignedPayload{}).HandleBuild(ctx, in, next)
return (&unsignedPayload{}).HandleFinalize(ctx, in, next)
}

// else fall back to signed payload
return (&computePayloadSHA256{}).HandleBuild(ctx, in, next)
return (&computePayloadSHA256{}).HandleFinalize(ctx, in, next)
}

// unsignedPayload sets the SigV4 request payload hash to unsigned.
Expand All @@ -104,31 +102,24 @@ type unsignedPayload struct{}
// AddUnsignedPayloadMiddleware adds unsignedPayload to the operation
// middleware stack
func AddUnsignedPayloadMiddleware(stack *middleware.Stack) error {
return stack.Build.Add(&unsignedPayload{}, middleware.After)
return stack.Finalize.Insert(&unsignedPayload{}, "ResolveEndpointV2", middleware.After)
}

// ID returns the unsignedPayload identifier
func (m *unsignedPayload) ID() string {
return computePayloadHashMiddlewareID
}

// HandleBuild sets the payload hash to be an unsigned payload
func (m *unsignedPayload) HandleBuild(
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
// HandleFinalize sets the payload hash magic value to the unsigned sentinel.
func (m *unsignedPayload) HandleFinalize(
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
) (
out middleware.BuildOutput, metadata middleware.Metadata, err error,
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
// This should not compute the content SHA256 if the value is already
// known. (e.g. application pre-computed SHA256 before making API call).
// Does not have any tight coupling to the X-Amz-Content-Sha256 header, if
// that header is provided a middleware must translate it into the context.
contentSHA := GetPayloadHash(ctx)
if len(contentSHA) == 0 {
contentSHA = v4Internal.UnsignedPayload
if GetPayloadHash(ctx) == "" {
ctx = SetPayloadHash(ctx, v4Internal.UnsignedPayload)
}

ctx = SetPayloadHash(ctx, contentSHA)
return next.HandleBuild(ctx, in)
return next.HandleFinalize(ctx, in)
}

// computePayloadSHA256 computes SHA256 payload hash to sign.
Expand All @@ -144,13 +135,13 @@ type computePayloadSHA256 struct{}
// AddComputePayloadSHA256Middleware adds computePayloadSHA256 to the
// operation middleware stack
func AddComputePayloadSHA256Middleware(stack *middleware.Stack) error {
return stack.Build.Add(&computePayloadSHA256{}, middleware.After)
return stack.Finalize.Insert(&computePayloadSHA256{}, "ResolveEndpointV2", middleware.After)
}

// RemoveComputePayloadSHA256Middleware removes computePayloadSHA256 from the
// operation middleware stack
func RemoveComputePayloadSHA256Middleware(stack *middleware.Stack) error {
_, err := stack.Build.Remove(computePayloadHashMiddlewareID)
_, err := stack.Finalize.Remove(computePayloadHashMiddlewareID)
return err
}

Expand All @@ -159,27 +150,24 @@ func (m *computePayloadSHA256) ID() string {
return computePayloadHashMiddlewareID
}

// HandleBuild compute the payload hash for the request payload
func (m *computePayloadSHA256) HandleBuild(
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
// HandleFinalize computes the payload hash for the request, storing it to the
// context. This is a no-op if a caller has previously set that value.
func (m *computePayloadSHA256) HandleFinalize(
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
) (
out middleware.BuildOutput, metadata middleware.Metadata, err error,
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
if GetPayloadHash(ctx) != "" {
return next.HandleFinalize(ctx, in)
}

req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &HashComputationError{
Err: fmt.Errorf("unexpected request middleware type %T", in.Request),
}
}

// This should not compute the content SHA256 if the value is already
// known. (e.g. application pre-computed SHA256 before making API call)
// Does not have any tight coupling to the X-Amz-Content-Sha256 header, if
// that header is provided a middleware must translate it into the context.
if contentSHA := GetPayloadHash(ctx); len(contentSHA) != 0 {
return next.HandleBuild(ctx, in)
}

hash := sha256.New()
if stream := req.GetStream(); stream != nil {
_, err = io.Copy(hash, stream)
Expand All @@ -198,7 +186,7 @@ func (m *computePayloadSHA256) HandleBuild(

ctx = SetPayloadHash(ctx, hex.EncodeToString(hash.Sum(nil)))

return next.HandleBuild(ctx, in)
return next.HandleFinalize(ctx, in)
}

// SwapComputePayloadSHA256ForUnsignedPayloadMiddleware replaces the
Expand All @@ -207,7 +195,7 @@ func (m *computePayloadSHA256) HandleBuild(
// Use this to disable computing the Payload SHA256 checksum and instead use
// UNSIGNED-PAYLOAD for the SHA256 value.
func SwapComputePayloadSHA256ForUnsignedPayloadMiddleware(stack *middleware.Stack) error {
_, err := stack.Build.Swap(computePayloadHashMiddlewareID, &unsignedPayload{})
_, err := stack.Finalize.Swap(computePayloadHashMiddlewareID, &unsignedPayload{})
return err
}

Expand All @@ -218,13 +206,13 @@ type contentSHA256Header struct{}
// AddContentSHA256HeaderMiddleware adds ContentSHA256Header to the
// operation middleware stack
func AddContentSHA256HeaderMiddleware(stack *middleware.Stack) error {
return stack.Build.Insert(&contentSHA256Header{}, computePayloadHashMiddlewareID, middleware.After)
return stack.Finalize.Insert(&contentSHA256Header{}, computePayloadHashMiddlewareID, middleware.After)
}

// RemoveContentSHA256HeaderMiddleware removes contentSHA256Header middleware
// from the operation middleware stack
func RemoveContentSHA256HeaderMiddleware(stack *middleware.Stack) error {
_, err := stack.Build.Remove((*contentSHA256Header)(nil).ID())
_, err := stack.Finalize.Remove((*contentSHA256Header)(nil).ID())
return err
}

Expand All @@ -233,21 +221,20 @@ func (m *contentSHA256Header) ID() string {
return "SigV4ContentSHA256Header"
}

// HandleBuild sets the X-Amz-Content-Sha256 header value to the Payload hash
// HandleFinalize sets the X-Amz-Content-Sha256 header value to the Payload hash
// stored in the context.
func (m *contentSHA256Header) HandleBuild(
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
func (m *contentSHA256Header) HandleFinalize(
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
) (
out middleware.BuildOutput, metadata middleware.Metadata, err error,
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &HashComputationError{Err: fmt.Errorf("unexpected request middleware type %T", in.Request)}
}

req.Header.Set(v4Internal.ContentSHAKey, GetPayloadHash(ctx))

return next.HandleBuild(ctx, in)
return next.HandleFinalize(ctx, in)
}

// SignHTTPRequestMiddlewareOptions is the configuration options for the SignHTTPRequestMiddleware middleware.
Expand Down Expand Up @@ -332,17 +319,17 @@ type streamingEventsPayload struct{}

// AddStreamingEventsPayload adds the streamingEventsPayload middleware to the stack.
func AddStreamingEventsPayload(stack *middleware.Stack) error {
return stack.Build.Add(&streamingEventsPayload{}, middleware.After)
return stack.Finalize.Add(&streamingEventsPayload{}, middleware.Before)
}

func (s *streamingEventsPayload) ID() string {
return computePayloadHashMiddlewareID
}

func (s *streamingEventsPayload) HandleBuild(
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
func (s *streamingEventsPayload) HandleFinalize(
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
) (
out middleware.BuildOutput, metadata middleware.Metadata, err error,
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
contentSHA := GetPayloadHash(ctx)
if len(contentSHA) == 0 {
Expand All @@ -351,7 +338,7 @@ func (s *streamingEventsPayload) HandleBuild(

ctx = SetPayloadHash(ctx, contentSHA)

return next.HandleBuild(ctx, in)
return next.HandleFinalize(ctx, in)
}

// GetSignedRequestSignature attempts to extract the signature of the request.
Expand Down
Loading
Loading