From 2db2d66ebae846ddf188afda7b677bd5d95e6d39 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Tue, 16 May 2023 12:28:12 -0400 Subject: [PATCH] authenticate: add aws cognito (#4137) --- authenticate/handlers.go | 2 +- internal/identity/oidc/cognito/cognito.go | 61 +++++++++++++++++++++++ internal/identity/providers.go | 3 ++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 internal/identity/oidc/cognito/cognito.go diff --git a/authenticate/handlers.go b/authenticate/handlers.go index 78557513b..9c4edb98f 100644 --- a/authenticate/handlers.go +++ b/authenticate/handlers.go @@ -271,7 +271,7 @@ func (a *Authenticate) signOutRedirect(w http.ResponseWriter, r *http.Request) e endSessionURL, err := authenticator.LogOut() if err == nil && redirectString != "" { - params := url.Values{} + params := endSessionURL.Query() params.Add("id_token_hint", rawIDToken) params.Add("post_logout_redirect_uri", redirectString) endSessionURL.RawQuery = params.Encode() diff --git a/internal/identity/oidc/cognito/cognito.go b/internal/identity/oidc/cognito/cognito.go new file mode 100644 index 000000000..74a88e9a0 --- /dev/null +++ b/internal/identity/oidc/cognito/cognito.go @@ -0,0 +1,61 @@ +// Package cognito provides support for AWS Cognito +package cognito + +import ( + "context" + "fmt" + "net/url" + + "github.com/pomerium/pomerium/internal/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" + "github.com/pomerium/pomerium/internal/urlutil" +) + +var defaultScopes = []string{"openid", "email", "profile"} + +// Name identifies the Cognito identity provider +const Name = "cognito" + +// Provider is an Cognito implementation of the Authenticator interface. +type Provider struct { + *pom_oidc.Provider +} + +// New instantiates an OpenID Connect (OIDC) provider for AWS Cognito. +func New(ctx context.Context, opts *oauth.Options) (*Provider, error) { + var p Provider + + if opts.Scopes == nil { + opts.Scopes = defaultScopes + } + + genericOIDC, err := pom_oidc.New(ctx, opts) + if err != nil { + return nil, fmt.Errorf("failed creating oidc provider: %w", err) + } + p.Provider = genericOIDC + + cognitoProvider, err := genericOIDC.GetProvider() + if err != nil { + return nil, fmt.Errorf("failed getting cognito provider: %w", err) + } + + cognitoURL, err := urlutil.ParseAndValidateURL(cognitoProvider.Endpoint().AuthURL) + if err != nil { + return nil, fmt.Errorf("cannot parse cognito auth url: %w", err) + } + + // https://docs.aws.amazon.com/cognito/latest/developerguide/revocation-endpoint.html + p.RevocationURL = cognitoURL.ResolveReference(&url.URL{Path: "/oauth2/revoke"}).String() + + // https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html + p.EndSessionURL = cognitoURL.ResolveReference(&url.URL{ + Path: "/logout", + RawQuery: url.Values{ + "client_id": []string{opts.ClientID}, + "logout_uri": []string{opts.RedirectURL.ResolveReference(&url.URL{Path: "/"}).String()}, + }.Encode(), + }).String() + + return &p, nil +} diff --git a/internal/identity/providers.go b/internal/identity/providers.go index 12fb69db7..f6fe06c57 100644 --- a/internal/identity/providers.go +++ b/internal/identity/providers.go @@ -16,6 +16,7 @@ import ( "github.com/pomerium/pomerium/internal/identity/oidc" "github.com/pomerium/pomerium/internal/identity/oidc/auth0" "github.com/pomerium/pomerium/internal/identity/oidc/azure" + "github.com/pomerium/pomerium/internal/identity/oidc/cognito" "github.com/pomerium/pomerium/internal/identity/oidc/gitlab" "github.com/pomerium/pomerium/internal/identity/oidc/google" "github.com/pomerium/pomerium/internal/identity/oidc/okta" @@ -58,6 +59,8 @@ func NewAuthenticator(o oauth.Options) (a Authenticator, err error) { a, err = onelogin.New(ctx, &o) case ping.Name: a, err = ping.New(ctx, &o) + case cognito.Name: + a, err = cognito.New(ctx, &o) case "": return nil, fmt.Errorf("identity: provider is not defined") default: