From 522749b5d89122db129198af1800b464ecf09019 Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Thu, 17 Nov 2016 15:20:41 -0800 Subject: [PATCH] *: switch oidc client to github.com/coreos/go-oidc This saves us from having to import two different versions of square/go-jose. --- cmd/example-app/main.go | 8 ++++---- connector/oidc/oidc.go | 8 ++++---- glide.yaml | 16 ++++++++------- server/server_test.go | 43 +++++++++++++++++++++++------------------ 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/cmd/example-app/main.go b/cmd/example-app/main.go index d2ada840..32728841 100644 --- a/cmd/example-app/main.go +++ b/cmd/example-app/main.go @@ -17,7 +17,7 @@ import ( "strings" "time" - "github.com/ericchiang/oidc" + "github.com/coreos/go-oidc" "github.com/spf13/cobra" "golang.org/x/net/context" "golang.org/x/oauth2" @@ -173,7 +173,7 @@ func cmd() *cobra.Command { } a.provider = provider - a.verifier = provider.NewVerifier(a.ctx, oidc.VerifyAudience(a.clientID)) + a.verifier = provider.Verifier(oidc.VerifyAudience(a.clientID)) http.HandleFunc("/", a.handleIndex) http.HandleFunc("/login", a.handleLogin) @@ -269,7 +269,7 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) { RefreshToken: refresh, Expiry: time.Now().Add(-time.Hour), } - token, err = oauth2Config.TokenSource(a.ctx, t).Token() + token, err = oauth2Config.TokenSource(r.Context(), t).Token() default: http.Error(w, fmt.Sprintf("no code in request: %q", r.Form), http.StatusBadRequest) return @@ -286,7 +286,7 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) { return } - idToken, err := a.verifier.Verify(rawIDToken) + idToken, err := a.verifier.Verify(r.Context(), rawIDToken) if err != nil { http.Error(w, fmt.Sprintf("Failed to verify ID token: %v", err), http.StatusInternalServerError) return diff --git a/connector/oidc/oidc.go b/connector/oidc/oidc.go index c9d88191..6a71d017 100644 --- a/connector/oidc/oidc.go +++ b/connector/oidc/oidc.go @@ -6,7 +6,7 @@ import ( "fmt" "net/http" - "github.com/ericchiang/oidc" + "github.com/coreos/go-oidc" "golang.org/x/net/context" "golang.org/x/oauth2" @@ -51,7 +51,7 @@ func (c *Config) Open() (conn connector.Connector, err error) { Scopes: scopes, RedirectURL: c.RedirectURI, }, - verifier: provider.NewVerifier(ctx, + verifier: provider.Verifier( oidc.VerifyExpiry(), oidc.VerifyAudience(clientID), ), @@ -99,7 +99,7 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide if errType := q.Get("error"); errType != "" { return identity, &oauth2Error{errType, q.Get("error_description")} } - token, err := c.oauth2Config.Exchange(c.ctx, q.Get("code")) + token, err := c.oauth2Config.Exchange(r.Context(), q.Get("code")) if err != nil { return identity, fmt.Errorf("oidc: failed to get token: %v", err) } @@ -108,7 +108,7 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide if !ok { return identity, errors.New("oidc: no id_token in token response") } - idToken, err := c.verifier.Verify(rawIDToken) + idToken, err := c.verifier.Verify(r.Context(), rawIDToken) if err != nil { return identity, fmt.Errorf("oidc: failed to verify ID Token: %v", err) } diff --git a/glide.yaml b/glide.yaml index 73be313a..bd16dab6 100644 --- a/glide.yaml +++ b/glide.yaml @@ -17,7 +17,7 @@ import: version: 4e86f4367175e39f69d9358a5f17b4dda270378d - package: gopkg.in/square/go-jose.v2 - version: f209f41628247c56938cb20ef51d589ddad6c30b + version: v2.0.0 subpackages: - cipher - json @@ -26,6 +26,7 @@ import: version: 6a513affb38dc9788b449d59ffed099b8de18fa0 subpackages: - context + - context/ctxhttp - http2 - http2/hpack - internal/timeseries @@ -49,16 +50,17 @@ import: subpackages: - bcrypt -- package: github.com/ericchiang/oidc - version: 1907f0e61549f9081f26bdf269f11603496c9dee +- package: github.com/coreos/go-oidc + version: 5a7f09ab5787e846efa7f56f4a08b6d6926d08c4 - package: github.com/pquerna/cachecontrol version: c97913dcbd76de40b051a9b4cd827f7eaeb7a868 -- package: gopkg.in/square/go-jose.v1 - version: v1.0.2 - package: golang.org/x/oauth2 version: 08c8d727d2392d18286f9f88ad775ad98f09ab33 -# Not actually imported but glide detects it. Consider adding subpackages to -# the oauth2 package to eliminate. + subpackages: [] +# The oauth2 package only imports the appengine code when it's given a +# specific build tags, but glide detects it anyway. +# +# https://github.com/golang/oauth2/blob/d5040cdd/client_appengine.go - package: google.golang.org/appengine version: 267c27e7492265b84fc6719503b14a1e17975d79 subpackages: diff --git a/server/server_test.go b/server/server_test.go index 6db67d5c..a5865dfa 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -3,6 +3,7 @@ package server import ( "crypto/rsa" "crypto/x509" + "encoding/json" "encoding/pem" "errors" "fmt" @@ -17,7 +18,7 @@ import ( "testing" "time" - "github.com/ericchiang/oidc" + oidc "github.com/coreos/go-oidc" "github.com/kylelemons/godebug/pretty" "golang.org/x/crypto/bcrypt" "golang.org/x/net/context" @@ -117,17 +118,21 @@ func TestDiscovery(t *testing.T) { if err != nil { t.Fatalf("failed to get provider: %v", err) } - required := []struct { - name, val string - }{ - {"issuer", p.Issuer}, - {"authorization_endpoint", p.AuthURL}, - {"token_endpoint", p.TokenURL}, - {"jwks_uri", p.JWKSURL}, + + var got map[string]*json.RawMessage + if err := p.Claims(&got); err != nil { + t.Fatalf("failed to decode claims: %v", err) + } + + required := []string{ + "issuer", + "authorization_endpoint", + "token_endpoint", + "jwks_uri", } for _, field := range required { - if field.val == "" { - t.Errorf("server discovery is missing required field %q", field.name) + if _, ok := got[field]; !ok { + t.Errorf("server discovery is missing required field %q", field) } } } @@ -169,7 +174,7 @@ func TestOAuth2CodeFlow(t *testing.T) { if !ok { return fmt.Errorf("no id token found") } - if _, err := p.NewVerifier(ctx).Verify(idToken); err != nil { + if _, err := p.Verifier().Verify(ctx, idToken); err != nil { return fmt.Errorf("failed to verify id token: %v", err) } return nil @@ -192,7 +197,7 @@ func TestOAuth2CodeFlow(t *testing.T) { if !ok { return fmt.Errorf("no id token found") } - idToken, err := p.NewVerifier(ctx).Verify(rawIDToken) + idToken, err := p.Verifier().Verify(ctx, rawIDToken) if err != nil { return fmt.Errorf("failed to verify id token: %v", err) } @@ -230,7 +235,7 @@ func TestOAuth2CodeFlow(t *testing.T) { v.Add("grant_type", "refresh_token") v.Add("refresh_token", token.RefreshToken) v.Add("scope", strings.Join(requestedScopes, " ")) - resp, err := http.PostForm(p.TokenURL, v) + resp, err := http.PostForm(p.Endpoint().TokenURL, v) if err != nil { return err } @@ -258,7 +263,7 @@ func TestOAuth2CodeFlow(t *testing.T) { // Since we support that client we choose to be more relaxed about // scope parsing, disregarding extra whitespace. v.Add("scope", " "+strings.Join(requestedScopes, " ")) - resp, err := http.PostForm(p.TokenURL, v) + resp, err := http.PostForm(p.Endpoint().TokenURL, v) if err != nil { return err } @@ -284,7 +289,7 @@ func TestOAuth2CodeFlow(t *testing.T) { v.Add("refresh_token", token.RefreshToken) // Request a scope that wasn't requestd initially. v.Add("scope", "oidc email profile") - resp, err := http.PostForm(p.TokenURL, v) + resp, err := http.PostForm(p.Endpoint().TokenURL, v) if err != nil { return err } @@ -335,7 +340,7 @@ func TestOAuth2CodeFlow(t *testing.T) { if !ok { return fmt.Errorf("no id_token in refreshed token") } - idToken, err := p.NewVerifier(ctx).Verify(rawIDToken) + idToken, err := p.Verifier().Verify(ctx, rawIDToken) if err != nil { return fmt.Errorf("failed to verify id token: %v", err) } @@ -547,7 +552,7 @@ func TestOAuth2ImplicitFlow(t *testing.T) { src := &nonceSource{nonce: nonce} - idTokenVerifier := p.NewVerifier(ctx, oidc.VerifyAudience(client.ID), oidc.VerifyNonce(src)) + idTokenVerifier := p.Verifier(oidc.VerifyAudience(client.ID), oidc.VerifyNonce(src)) oauth2Config = &oauth2.Config{ ClientID: client.ID, @@ -569,7 +574,7 @@ func TestOAuth2ImplicitFlow(t *testing.T) { if idToken == "" { return errors.New("no id_token in fragment") } - if _, err := idTokenVerifier.Verify(idToken); err != nil { + if _, err := idTokenVerifier.Verify(ctx, idToken); err != nil { return fmt.Errorf("failed to verify id_token: %v", err) } return nil @@ -664,7 +669,7 @@ func TestCrossClientScopes(t *testing.T) { t.Errorf("no id token found: %v", err) return } - idToken, err := p.NewVerifier(ctx).Verify(rawIDToken) + idToken, err := p.Verifier().Verify(ctx, rawIDToken) if err != nil { t.Errorf("failed to parse ID Token: %v", err) return