auth.go (10598B)
1 // Code generated by smithy-go-codegen DO NOT EDIT. 2 3 package sso 4 5 import ( 6 "context" 7 "fmt" 8 awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" 9 smithy "github.com/aws/smithy-go" 10 smithyauth "github.com/aws/smithy-go/auth" 11 "github.com/aws/smithy-go/metrics" 12 "github.com/aws/smithy-go/middleware" 13 "github.com/aws/smithy-go/tracing" 14 smithyhttp "github.com/aws/smithy-go/transport/http" 15 "slices" 16 "strings" 17 ) 18 19 func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { 20 params.Region = options.Region 21 } 22 23 type setLegacyContextSigningOptionsMiddleware struct { 24 } 25 26 func (*setLegacyContextSigningOptionsMiddleware) ID() string { 27 return "setLegacyContextSigningOptions" 28 } 29 30 func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( 31 out middleware.FinalizeOutput, metadata middleware.Metadata, err error, 32 ) { 33 rscheme := getResolvedAuthScheme(ctx) 34 schemeID := rscheme.Scheme.SchemeID() 35 36 if sn := awsmiddleware.GetSigningName(ctx); sn != "" { 37 if schemeID == "aws.auth#sigv4" { 38 smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn) 39 } else if schemeID == "aws.auth#sigv4a" { 40 smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn) 41 } 42 } 43 44 if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" { 45 if schemeID == "aws.auth#sigv4" { 46 smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr) 47 } else if schemeID == "aws.auth#sigv4a" { 48 smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr}) 49 } 50 } 51 52 return next.HandleFinalize(ctx, in) 53 } 54 55 func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error { 56 return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before) 57 } 58 59 type withAnonymous struct { 60 resolver AuthSchemeResolver 61 } 62 63 var _ AuthSchemeResolver = (*withAnonymous)(nil) 64 65 func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { 66 opts, err := v.resolver.ResolveAuthSchemes(ctx, params) 67 if err != nil { 68 return nil, err 69 } 70 71 opts = append(opts, &smithyauth.Option{ 72 SchemeID: smithyauth.SchemeIDAnonymous, 73 }) 74 return opts, nil 75 } 76 77 func wrapWithAnonymousAuth(options *Options) { 78 if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok { 79 return 80 } 81 82 options.AuthSchemeResolver = &withAnonymous{ 83 resolver: options.AuthSchemeResolver, 84 } 85 } 86 87 // AuthResolverParameters contains the set of inputs necessary for auth scheme 88 // resolution. 89 type AuthResolverParameters struct { 90 // The name of the operation being invoked. 91 Operation string 92 93 // The region in which the operation is being invoked. 94 Region string 95 } 96 97 func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters { 98 params := &AuthResolverParameters{ 99 Operation: operation, 100 } 101 102 bindAuthParamsRegion(ctx, params, input, options) 103 104 return params 105 } 106 107 // AuthSchemeResolver returns a set of possible authentication options for an 108 // operation. 109 type AuthSchemeResolver interface { 110 ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error) 111 } 112 113 type defaultAuthSchemeResolver struct{} 114 115 var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil) 116 117 func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { 118 if overrides, ok := operationAuthOptions[params.Operation]; ok { 119 return overrides(params), nil 120 } 121 return serviceAuthOptions(params), nil 122 } 123 124 var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{ 125 "GetRoleCredentials": func(params *AuthResolverParameters) []*smithyauth.Option { 126 return []*smithyauth.Option{ 127 {SchemeID: smithyauth.SchemeIDAnonymous}, 128 } 129 }, 130 131 "ListAccountRoles": func(params *AuthResolverParameters) []*smithyauth.Option { 132 return []*smithyauth.Option{ 133 {SchemeID: smithyauth.SchemeIDAnonymous}, 134 } 135 }, 136 137 "ListAccounts": func(params *AuthResolverParameters) []*smithyauth.Option { 138 return []*smithyauth.Option{ 139 {SchemeID: smithyauth.SchemeIDAnonymous}, 140 } 141 }, 142 143 "Logout": func(params *AuthResolverParameters) []*smithyauth.Option { 144 return []*smithyauth.Option{ 145 {SchemeID: smithyauth.SchemeIDAnonymous}, 146 } 147 }, 148 } 149 150 func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option { 151 return []*smithyauth.Option{ 152 { 153 SchemeID: smithyauth.SchemeIDSigV4, 154 SignerProperties: func() smithy.Properties { 155 var props smithy.Properties 156 smithyhttp.SetSigV4SigningName(&props, "awsssoportal") 157 smithyhttp.SetSigV4SigningRegion(&props, params.Region) 158 return props 159 }(), 160 }, 161 } 162 } 163 164 type resolveAuthSchemeMiddleware struct { 165 operation string 166 options Options 167 } 168 169 func (*resolveAuthSchemeMiddleware) ID() string { 170 return "ResolveAuthScheme" 171 } 172 173 func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( 174 out middleware.FinalizeOutput, metadata middleware.Metadata, err error, 175 ) { 176 _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") 177 defer span.End() 178 179 params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) 180 options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) 181 if err != nil { 182 return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) 183 } 184 185 scheme, ok := m.selectScheme(options) 186 if !ok { 187 return out, metadata, fmt.Errorf("could not select an auth scheme") 188 } 189 190 ctx = setResolvedAuthScheme(ctx, scheme) 191 192 span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID()) 193 span.End() 194 return next.HandleFinalize(ctx, in) 195 } 196 197 func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { 198 sorted := sortAuthOptions(options, m.options.AuthSchemePreference) 199 for _, option := range sorted { 200 if option.SchemeID == smithyauth.SchemeIDAnonymous { 201 return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true 202 } 203 204 for _, scheme := range m.options.AuthSchemes { 205 if scheme.SchemeID() != option.SchemeID { 206 continue 207 } 208 209 if scheme.IdentityResolver(m.options) != nil { 210 return newResolvedAuthScheme(scheme, option), true 211 } 212 } 213 } 214 215 return nil, false 216 } 217 218 func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { 219 byPriority := make([]*smithyauth.Option, 0, len(options)) 220 for _, prefName := range preferred { 221 for _, option := range options { 222 optName := option.SchemeID 223 if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { 224 optName = parts[1] 225 } 226 if prefName == optName { 227 byPriority = append(byPriority, option) 228 } 229 } 230 } 231 for _, option := range options { 232 if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { 233 return o.SchemeID == option.SchemeID 234 }) { 235 byPriority = append(byPriority, option) 236 } 237 } 238 return byPriority 239 } 240 241 type resolvedAuthSchemeKey struct{} 242 243 type resolvedAuthScheme struct { 244 Scheme smithyhttp.AuthScheme 245 IdentityProperties smithy.Properties 246 SignerProperties smithy.Properties 247 } 248 249 func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme { 250 return &resolvedAuthScheme{ 251 Scheme: scheme, 252 IdentityProperties: option.IdentityProperties, 253 SignerProperties: option.SignerProperties, 254 } 255 } 256 257 func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context { 258 return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme) 259 } 260 261 func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme { 262 v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme) 263 return v 264 } 265 266 type getIdentityMiddleware struct { 267 options Options 268 } 269 270 func (*getIdentityMiddleware) ID() string { 271 return "GetIdentity" 272 } 273 274 func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( 275 out middleware.FinalizeOutput, metadata middleware.Metadata, err error, 276 ) { 277 innerCtx, span := tracing.StartSpan(ctx, "GetIdentity") 278 defer span.End() 279 280 rscheme := getResolvedAuthScheme(innerCtx) 281 if rscheme == nil { 282 return out, metadata, fmt.Errorf("no resolved auth scheme") 283 } 284 285 resolver := rscheme.Scheme.IdentityResolver(m.options) 286 if resolver == nil { 287 return out, metadata, fmt.Errorf("no identity resolver") 288 } 289 290 identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration", 291 func() (smithyauth.Identity, error) { 292 return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties) 293 }, 294 func(o *metrics.RecordMetricOptions) { 295 o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) 296 }) 297 if err != nil { 298 return out, metadata, fmt.Errorf("get identity: %w", err) 299 } 300 301 ctx = setIdentity(ctx, identity) 302 303 span.End() 304 return next.HandleFinalize(ctx, in) 305 } 306 307 type identityKey struct{} 308 309 func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context { 310 return middleware.WithStackValue(ctx, identityKey{}, identity) 311 } 312 313 func getIdentity(ctx context.Context) smithyauth.Identity { 314 v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity) 315 return v 316 } 317 318 type signRequestMiddleware struct { 319 options Options 320 } 321 322 func (*signRequestMiddleware) ID() string { 323 return "Signing" 324 } 325 326 func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( 327 out middleware.FinalizeOutput, metadata middleware.Metadata, err error, 328 ) { 329 _, span := tracing.StartSpan(ctx, "SignRequest") 330 defer span.End() 331 332 req, ok := in.Request.(*smithyhttp.Request) 333 if !ok { 334 return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request) 335 } 336 337 rscheme := getResolvedAuthScheme(ctx) 338 if rscheme == nil { 339 return out, metadata, fmt.Errorf("no resolved auth scheme") 340 } 341 342 identity := getIdentity(ctx) 343 if identity == nil { 344 return out, metadata, fmt.Errorf("no identity") 345 } 346 347 signer := rscheme.Scheme.Signer() 348 if signer == nil { 349 return out, metadata, fmt.Errorf("no signer") 350 } 351 352 _, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) { 353 return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties) 354 }, func(o *metrics.RecordMetricOptions) { 355 o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) 356 }) 357 if err != nil { 358 return out, metadata, fmt.Errorf("sign request: %w", err) 359 } 360 361 span.End() 362 return next.HandleFinalize(ctx, in) 363 }