Commit 522749b5 authored by Eric Chiang's avatar Eric Chiang

*: switch oidc client to github.com/coreos/go-oidc

This saves us from having to import two different versions of
square/go-jose.
parent 5ed42be7
...@@ -17,7 +17,7 @@ import ( ...@@ -17,7 +17,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/ericchiang/oidc" "github.com/coreos/go-oidc"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/net/context" "golang.org/x/net/context"
"golang.org/x/oauth2" "golang.org/x/oauth2"
...@@ -173,7 +173,7 @@ func cmd() *cobra.Command { ...@@ -173,7 +173,7 @@ func cmd() *cobra.Command {
} }
a.provider = provider 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("/", a.handleIndex)
http.HandleFunc("/login", a.handleLogin) http.HandleFunc("/login", a.handleLogin)
...@@ -269,7 +269,7 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) { ...@@ -269,7 +269,7 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) {
RefreshToken: refresh, RefreshToken: refresh,
Expiry: time.Now().Add(-time.Hour), Expiry: time.Now().Add(-time.Hour),
} }
token, err = oauth2Config.TokenSource(a.ctx, t).Token() token, err = oauth2Config.TokenSource(r.Context(), t).Token()
default: default:
http.Error(w, fmt.Sprintf("no code in request: %q", r.Form), http.StatusBadRequest) http.Error(w, fmt.Sprintf("no code in request: %q", r.Form), http.StatusBadRequest)
return return
...@@ -286,7 +286,7 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) { ...@@ -286,7 +286,7 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) {
return return
} }
idToken, err := a.verifier.Verify(rawIDToken) idToken, err := a.verifier.Verify(r.Context(), rawIDToken)
if err != nil { if err != nil {
http.Error(w, fmt.Sprintf("Failed to verify ID token: %v", err), http.StatusInternalServerError) http.Error(w, fmt.Sprintf("Failed to verify ID token: %v", err), http.StatusInternalServerError)
return return
......
...@@ -6,7 +6,7 @@ import ( ...@@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/ericchiang/oidc" "github.com/coreos/go-oidc"
"golang.org/x/net/context" "golang.org/x/net/context"
"golang.org/x/oauth2" "golang.org/x/oauth2"
...@@ -51,7 +51,7 @@ func (c *Config) Open() (conn connector.Connector, err error) { ...@@ -51,7 +51,7 @@ func (c *Config) Open() (conn connector.Connector, err error) {
Scopes: scopes, Scopes: scopes,
RedirectURL: c.RedirectURI, RedirectURL: c.RedirectURI,
}, },
verifier: provider.NewVerifier(ctx, verifier: provider.Verifier(
oidc.VerifyExpiry(), oidc.VerifyExpiry(),
oidc.VerifyAudience(clientID), oidc.VerifyAudience(clientID),
), ),
...@@ -99,7 +99,7 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide ...@@ -99,7 +99,7 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide
if errType := q.Get("error"); errType != "" { if errType := q.Get("error"); errType != "" {
return identity, &oauth2Error{errType, q.Get("error_description")} 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 { if err != nil {
return identity, fmt.Errorf("oidc: failed to get token: %v", err) 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 ...@@ -108,7 +108,7 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide
if !ok { if !ok {
return identity, errors.New("oidc: no id_token in token response") 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 { if err != nil {
return identity, fmt.Errorf("oidc: failed to verify ID Token: %v", err) return identity, fmt.Errorf("oidc: failed to verify ID Token: %v", err)
} }
......
...@@ -17,7 +17,7 @@ import: ...@@ -17,7 +17,7 @@ import:
version: 4e86f4367175e39f69d9358a5f17b4dda270378d version: 4e86f4367175e39f69d9358a5f17b4dda270378d
- package: gopkg.in/square/go-jose.v2 - package: gopkg.in/square/go-jose.v2
version: f209f41628247c56938cb20ef51d589ddad6c30b version: v2.0.0
subpackages: subpackages:
- cipher - cipher
- json - json
...@@ -26,6 +26,7 @@ import: ...@@ -26,6 +26,7 @@ import:
version: 6a513affb38dc9788b449d59ffed099b8de18fa0 version: 6a513affb38dc9788b449d59ffed099b8de18fa0
subpackages: subpackages:
- context - context
- context/ctxhttp
- http2 - http2
- http2/hpack - http2/hpack
- internal/timeseries - internal/timeseries
...@@ -49,16 +50,17 @@ import: ...@@ -49,16 +50,17 @@ import:
subpackages: subpackages:
- bcrypt - bcrypt
- package: github.com/ericchiang/oidc - package: github.com/coreos/go-oidc
version: 1907f0e61549f9081f26bdf269f11603496c9dee version: 5a7f09ab5787e846efa7f56f4a08b6d6926d08c4
- package: github.com/pquerna/cachecontrol - package: github.com/pquerna/cachecontrol
version: c97913dcbd76de40b051a9b4cd827f7eaeb7a868 version: c97913dcbd76de40b051a9b4cd827f7eaeb7a868
- package: gopkg.in/square/go-jose.v1
version: v1.0.2
- package: golang.org/x/oauth2 - package: golang.org/x/oauth2
version: 08c8d727d2392d18286f9f88ad775ad98f09ab33 version: 08c8d727d2392d18286f9f88ad775ad98f09ab33
# Not actually imported but glide detects it. Consider adding subpackages to subpackages: []
# the oauth2 package to eliminate. # 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 - package: google.golang.org/appengine
version: 267c27e7492265b84fc6719503b14a1e17975d79 version: 267c27e7492265b84fc6719503b14a1e17975d79
subpackages: subpackages:
......
...@@ -3,6 +3,7 @@ package server ...@@ -3,6 +3,7 @@ package server
import ( import (
"crypto/rsa" "crypto/rsa"
"crypto/x509" "crypto/x509"
"encoding/json"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
...@@ -17,7 +18,7 @@ import ( ...@@ -17,7 +18,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/ericchiang/oidc" oidc "github.com/coreos/go-oidc"
"github.com/kylelemons/godebug/pretty" "github.com/kylelemons/godebug/pretty"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"golang.org/x/net/context" "golang.org/x/net/context"
...@@ -117,17 +118,21 @@ func TestDiscovery(t *testing.T) { ...@@ -117,17 +118,21 @@ func TestDiscovery(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("failed to get provider: %v", err) t.Fatalf("failed to get provider: %v", err)
} }
required := []struct {
name, val string var got map[string]*json.RawMessage
}{ if err := p.Claims(&got); err != nil {
{"issuer", p.Issuer}, t.Fatalf("failed to decode claims: %v", err)
{"authorization_endpoint", p.AuthURL}, }
{"token_endpoint", p.TokenURL},
{"jwks_uri", p.JWKSURL}, required := []string{
"issuer",
"authorization_endpoint",
"token_endpoint",
"jwks_uri",
} }
for _, field := range required { for _, field := range required {
if field.val == "" { if _, ok := got[field]; !ok {
t.Errorf("server discovery is missing required field %q", field.name) t.Errorf("server discovery is missing required field %q", field)
} }
} }
} }
...@@ -169,7 +174,7 @@ func TestOAuth2CodeFlow(t *testing.T) { ...@@ -169,7 +174,7 @@ func TestOAuth2CodeFlow(t *testing.T) {
if !ok { if !ok {
return fmt.Errorf("no id token found") 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 fmt.Errorf("failed to verify id token: %v", err)
} }
return nil return nil
...@@ -192,7 +197,7 @@ func TestOAuth2CodeFlow(t *testing.T) { ...@@ -192,7 +197,7 @@ func TestOAuth2CodeFlow(t *testing.T) {
if !ok { if !ok {
return fmt.Errorf("no id token found") return fmt.Errorf("no id token found")
} }
idToken, err := p.NewVerifier(ctx).Verify(rawIDToken) idToken, err := p.Verifier().Verify(ctx, rawIDToken)
if err != nil { if err != nil {
return fmt.Errorf("failed to verify id token: %v", err) return fmt.Errorf("failed to verify id token: %v", err)
} }
...@@ -230,7 +235,7 @@ func TestOAuth2CodeFlow(t *testing.T) { ...@@ -230,7 +235,7 @@ func TestOAuth2CodeFlow(t *testing.T) {
v.Add("grant_type", "refresh_token") v.Add("grant_type", "refresh_token")
v.Add("refresh_token", token.RefreshToken) v.Add("refresh_token", token.RefreshToken)
v.Add("scope", strings.Join(requestedScopes, " ")) v.Add("scope", strings.Join(requestedScopes, " "))
resp, err := http.PostForm(p.TokenURL, v) resp, err := http.PostForm(p.Endpoint().TokenURL, v)
if err != nil { if err != nil {
return err return err
} }
...@@ -258,7 +263,7 @@ func TestOAuth2CodeFlow(t *testing.T) { ...@@ -258,7 +263,7 @@ func TestOAuth2CodeFlow(t *testing.T) {
// Since we support that client we choose to be more relaxed about // Since we support that client we choose to be more relaxed about
// scope parsing, disregarding extra whitespace. // scope parsing, disregarding extra whitespace.
v.Add("scope", " "+strings.Join(requestedScopes, " ")) v.Add("scope", " "+strings.Join(requestedScopes, " "))
resp, err := http.PostForm(p.TokenURL, v) resp, err := http.PostForm(p.Endpoint().TokenURL, v)
if err != nil { if err != nil {
return err return err
} }
...@@ -284,7 +289,7 @@ func TestOAuth2CodeFlow(t *testing.T) { ...@@ -284,7 +289,7 @@ func TestOAuth2CodeFlow(t *testing.T) {
v.Add("refresh_token", token.RefreshToken) v.Add("refresh_token", token.RefreshToken)
// Request a scope that wasn't requestd initially. // Request a scope that wasn't requestd initially.
v.Add("scope", "oidc email profile") v.Add("scope", "oidc email profile")
resp, err := http.PostForm(p.TokenURL, v) resp, err := http.PostForm(p.Endpoint().TokenURL, v)
if err != nil { if err != nil {
return err return err
} }
...@@ -335,7 +340,7 @@ func TestOAuth2CodeFlow(t *testing.T) { ...@@ -335,7 +340,7 @@ func TestOAuth2CodeFlow(t *testing.T) {
if !ok { if !ok {
return fmt.Errorf("no id_token in refreshed token") 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 { if err != nil {
return fmt.Errorf("failed to verify id token: %v", err) return fmt.Errorf("failed to verify id token: %v", err)
} }
...@@ -547,7 +552,7 @@ func TestOAuth2ImplicitFlow(t *testing.T) { ...@@ -547,7 +552,7 @@ func TestOAuth2ImplicitFlow(t *testing.T) {
src := &nonceSource{nonce: nonce} 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{ oauth2Config = &oauth2.Config{
ClientID: client.ID, ClientID: client.ID,
...@@ -569,7 +574,7 @@ func TestOAuth2ImplicitFlow(t *testing.T) { ...@@ -569,7 +574,7 @@ func TestOAuth2ImplicitFlow(t *testing.T) {
if idToken == "" { if idToken == "" {
return errors.New("no id_token in fragment") 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 fmt.Errorf("failed to verify id_token: %v", err)
} }
return nil return nil
...@@ -664,7 +669,7 @@ func TestCrossClientScopes(t *testing.T) { ...@@ -664,7 +669,7 @@ func TestCrossClientScopes(t *testing.T) {
t.Errorf("no id token found: %v", err) t.Errorf("no id token found: %v", err)
return return
} }
idToken, err := p.NewVerifier(ctx).Verify(rawIDToken) idToken, err := p.Verifier().Verify(ctx, rawIDToken)
if err != nil { if err != nil {
t.Errorf("failed to parse ID Token: %v", err) t.Errorf("failed to parse ID Token: %v", err)
return return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment