*: switch oidc client to github.com/coreos/go-oidc
This saves us from having to import two different versions of square/go-jose.
This commit is contained in:
parent
5ed42be7a5
commit
522749b5d8
4 changed files with 41 additions and 34 deletions
|
@ -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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
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) {
|
||||||
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 (
|
||||||
"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) {
|
||||||
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
|
||||||
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
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
16
glide.yaml
16
glide.yaml
|
@ -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:
|
||||||
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:
|
||||||
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
|
||||||
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 (
|
||||||
"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) {
|
||||||
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) {
|
||||||
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) {
|
||||||
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) {
|
||||||
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) {
|
||||||
// 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) {
|
||||||
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) {
|
||||||
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) {
|
||||||
|
|
||||||
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) {
|
||||||
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) {
|
||||||
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
|
||||||
|
|
Reference in a new issue