auth.go 10 KB

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