mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-02-14 18:10:17 +00:00
upgrade github.com/go-jose/go-jose and github.com/coreos/go-oidc
Also standardize some related imports and fix some whitespace in a test
This commit is contained in:
@@ -109,11 +109,17 @@ linters-settings:
|
||||
# k8s.io
|
||||
- pkg: k8s.io/api/core/v1
|
||||
alias: corev1
|
||||
# OAuth2/OIDC/Fosite
|
||||
# OAuth2/OIDC/Fosite/JOSE
|
||||
- pkg: github.com/coreos/go-oidc/v3/oidc
|
||||
alias: coreosoidc
|
||||
- pkg: github.com/ory/fosite/handler/oauth2
|
||||
alias: fositeoauth2
|
||||
- pkg: github.com/ory/fosite/token/jwt
|
||||
alias: fositejwt
|
||||
- pkg: github.com/go-jose/go-jose/v4/jwt
|
||||
alias: josejwt
|
||||
- pkg: github.com/go-jose/go-jose/v3
|
||||
alias: oldjosev3
|
||||
# Generated Pinniped
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1
|
||||
alias: authenticationv1alpha1
|
||||
|
||||
5
go.mod
5
go.mod
@@ -26,10 +26,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => go.op
|
||||
// This is an indirect dep which has CVE-2023-45142, so replace it with the fixed version.
|
||||
replace go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace => go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.44.0
|
||||
|
||||
// https://github.com/coreos/go-oidc/releases/tag/v3.10.0 starts to use https://github.com/go-jose/go-jose/releases/tag/v4.0.0.
|
||||
// Unfortunately this has breaking changes.
|
||||
replace github.com/coreos/go-oidc/v3 => github.com/coreos/go-oidc/v3 v3.9.0
|
||||
|
||||
require (
|
||||
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
||||
github.com/chromedp/cdproto v0.0.0-20240614221651-cc28c8fb63e7
|
||||
@@ -40,6 +36,7 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/felixge/httpsnoop v1.0.4
|
||||
github.com/go-jose/go-jose/v3 v3.0.3
|
||||
github.com/go-jose/go-jose/v4 v4.0.2
|
||||
github.com/go-ldap/ldap/v3 v3.4.8
|
||||
github.com/go-logr/logr v1.4.2
|
||||
github.com/go-logr/stdr v1.2.2
|
||||
|
||||
6
go.sum
6
go.sum
@@ -87,8 +87,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo=
|
||||
github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4=
|
||||
github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU=
|
||||
github.com/coreos/go-oidc/v3 v3.10.0/go.mod h1:5j11xcw0D3+SGxn6Z/WFADsgcWVMyNAlSQupk0KK3ac=
|
||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
@@ -150,6 +150,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
|
||||
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ=
|
||||
github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk=
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"time"
|
||||
|
||||
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -75,7 +75,18 @@ const (
|
||||
defaultUsernameClaim = oidcapi.IDTokenClaimUsername
|
||||
defaultGroupsClaim = oidcapi.IDTokenClaimGroups
|
||||
|
||||
minimalJWTToTriggerJWKSFetch = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.e30."
|
||||
// This hardcoded JWT will be used below to trick coreosoidc.RemoteKeySet into immediately fetching the remote JWKS.
|
||||
// Unfortunately, coreosoidc.RemoteKeySet has no public API to ask it to perform this fetch. However, calling
|
||||
// VerifySignature() and passing in any valid JWT will cause it to immediately fetch the remote JWKS, and return
|
||||
// any errors that might have occurred during the fetch. This controller wants to be able to tell the user
|
||||
// about those fetch errors to aid in user debugging of configuration. It is also a benefit for the in-memory
|
||||
// cached authenticator to have already preloaded the JWKS, so it is immediately ready to perform authentications.
|
||||
// Because we are passing a hardcoded JWT that was signed by a randomly generated signing key, the code below
|
||||
// expects that VerifySignature() should always return a signature error for this JWT (with the side effect of
|
||||
// fetching the remote JWKS) because no OIDC provider in the world should be using this signing key in its JWKS.
|
||||
// If somehow this JWT is considered verified by a remote JWKS, then the code below will treat it as an error.
|
||||
// This JWT and its signing key will not be used for any other purpose.
|
||||
minimalJWTToTriggerJWKSFetch = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.e30.bqGS21VimxEQES46lfR6-AKt_IQjZKykJGD7uyfer2QAp9d63lzcKZJq8qLj-hnLDJFnvy8F2IU1w26n4RX8s5IWxtkaeS2IZctruZzxg-TngPv4yslOznTPROIx_YOk8TMoz6-qTXWUjVTsu4RcVFnbFtdhRF0V-rfdL7Fah_DGxQM2lteb1nPB0hcN81Q8ony5Kw-NxKIpXXGr977u_SYqnafhlYIyL8W4iMN39xO3F7U3JuiySOUmJjBQPd7jL2XnWQwVcxpiZkjzWpnfEX-jqORMzDMRhbD3EfCBJsc-8NQvC4E9VoIgw2KEsfRHhyPyHITGzYOU7XUA5MnBKg"
|
||||
)
|
||||
|
||||
type providerJSON struct {
|
||||
@@ -452,15 +463,14 @@ func (c *jwtCacheFillerController) validateJWKSFetch(ctx context.Context, jwksUR
|
||||
// fetch the keys at all.
|
||||
_, verifyWithKeySetErr := keySet.VerifySignature(ctx, minimalJWTToTriggerJWKSFetch)
|
||||
if verifyWithKeySetErr == nil {
|
||||
// No unit test.
|
||||
// Since we hard-coded this token we expect there to always be a verification error.
|
||||
// The purpose of this function is really to test if we can get the JWKS, not to actually validate a token.
|
||||
// Therefore, we should never hit this path, nevertheless, lets handle just in case something unexpected happens.
|
||||
errText := "jwks should not have verified unsigned jwt token"
|
||||
errText := "remote jwks should not have been able to verify hardcoded test jwt token"
|
||||
conditions = append(conditions, &metav1.Condition{
|
||||
Type: typeJWKSFetchValid,
|
||||
Status: metav1.ConditionUnknown,
|
||||
Reason: reasonUnableToValidate,
|
||||
Status: metav1.ConditionFalse,
|
||||
Reason: reasonInvalidCouldNotFetchJWKS,
|
||||
Message: errText,
|
||||
})
|
||||
return nil, conditions, errors.New(errText)
|
||||
|
||||
@@ -10,7 +10,10 @@ import (
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -18,10 +21,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v3/jwt"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
josejwt "github.com/go-jose/go-jose/v4/jwt"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -46,11 +48,42 @@ import (
|
||||
"go.pinniped.dev/internal/testutil/tlsserver"
|
||||
)
|
||||
|
||||
// This private key was randomly generated and then used to sign a single JWT.
|
||||
// That JWT is hardcoded as the constant minimalJWTToTriggerJWKSFetch.
|
||||
// TestMinimalJWTToTriggerJWKSFetch below shows how that JWT was created.
|
||||
// This JWT will be used for only one purpose: to trick coreos.RemoteKeySet
|
||||
// into fetching a remote JWKS immediately. Because we expect that there is no
|
||||
// OIDC provider in the world that uses this randomly generated signing key,
|
||||
// then we can safely assume that this JWT should never successfully verify
|
||||
// using the real JWKS of any OIDC provider. If somehow it did verify, the
|
||||
// production code in the controller would consider that to be an error and
|
||||
// would refuse to load that JWTAuthenticator. The production code wants to
|
||||
// get a signature error, which means that the remote JWKS was successfully
|
||||
// loaded.
|
||||
//
|
||||
// This key was created using:
|
||||
//
|
||||
// key, _ := rsa.GenerateKey(rand.Reader, 2048)
|
||||
// t.Log(string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})))
|
||||
//
|
||||
//go:embed testdata/test.key
|
||||
var rsaPrivateKeyToSignMinimalJWTToTriggerJWKSFetch string
|
||||
|
||||
func TestMinimalJWTToTriggerJWKSFetch(t *testing.T) {
|
||||
tinyJWT := fositejwt.NewWithClaims(fositejwt.SigningMethodNone, fositejwt.MapClaims{})
|
||||
tinyJWTStr, err := tinyJWT.SignedString(fositejwt.UnsafeAllowNoneSignatureType)
|
||||
hardcodedPEMDecoded, _ := pem.Decode([]byte(rsaPrivateKeyToSignMinimalJWTToTriggerJWKSFetch))
|
||||
require.NotNil(t, hardcodedPEMDecoded, "failed to parse hardcoded PEM")
|
||||
hardcodedPrivateKey, err := x509.ParsePKCS1PrivateKey(hardcodedPEMDecoded.Bytes)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tinyJWTStr, minimalJWTToTriggerJWKSFetch)
|
||||
|
||||
signer, err := jose.NewSigner(
|
||||
jose.SigningKey{Algorithm: jose.RS256, Key: hardcodedPrivateKey},
|
||||
(&jose.SignerOptions{}).WithType("JWT"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
jwt, err := josejwt.Signed(signer).Claims(josejwt.Claims{}).Serialize()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, jwt, minimalJWTToTriggerJWKSFetch)
|
||||
}
|
||||
|
||||
func TestController(t *testing.T) {
|
||||
@@ -62,6 +95,11 @@ func TestController(t *testing.T) {
|
||||
goodAudience = "some-audience"
|
||||
)
|
||||
|
||||
hardcodedPEMDecoded, _ := pem.Decode([]byte(rsaPrivateKeyToSignMinimalJWTToTriggerJWKSFetch))
|
||||
require.NotNil(t, hardcodedPEMDecoded, "failed to parse hardcoded PEM")
|
||||
hardcodedPrivateKey, err := x509.ParsePKCS1PrivateKey(hardcodedPEMDecoded.Bytes)
|
||||
require.NoError(t, err)
|
||||
|
||||
goodECSigningKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
goodECSigningAlgo := jose.ES256
|
||||
require.NoError(t, err)
|
||||
@@ -122,12 +160,12 @@ func TestController(t *testing.T) {
|
||||
// A sub (subject) Claim SHOULD NOT be returned from the Claims Provider unless its value
|
||||
// is an identifier for the End-User at the Claims Provider (and not for the OpenID Provider or another party);
|
||||
// this typically means that a sub Claim SHOULD NOT be provided.
|
||||
claimsWithoutSubject := jwt.Claims{
|
||||
claimsWithoutSubject := josejwt.Claims{
|
||||
Issuer: goodOIDCIssuerServer.URL,
|
||||
Audience: []string{goodAudience},
|
||||
Expiry: jwt.NewNumericDate(time.Now().Add(time.Hour)),
|
||||
NotBefore: jwt.NewNumericDate(time.Now().Add(-time.Hour)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now().Add(-time.Hour)),
|
||||
Expiry: josejwt.NewNumericDate(time.Now().Add(time.Hour)),
|
||||
NotBefore: josejwt.NewNumericDate(time.Now().Add(-time.Hour)),
|
||||
IssuedAt: josejwt.NewNumericDate(time.Now().Add(-time.Hour)),
|
||||
}
|
||||
goodMux.Handle("/claim_source", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Unfortunately we have to set this up pretty early in the test because we can't redeclare
|
||||
@@ -139,12 +177,12 @@ func TestController(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
builder := jwt.Signed(sig).Claims(claimsWithoutSubject)
|
||||
builder := josejwt.Signed(sig).Claims(claimsWithoutSubject)
|
||||
|
||||
builder = builder.Claims(map[string]any{customGroupsClaim: distributedGroups})
|
||||
builder = builder.Claims(map[string]any{"groups": distributedGroups})
|
||||
|
||||
distributedClaimsJwt, err := builder.CompactSerialize()
|
||||
distributedClaimsJwt, err := builder.Serialize()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = w.Write([]byte(distributedClaimsJwt))
|
||||
@@ -160,11 +198,11 @@ func TestController(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
builder := jwt.Signed(sig).Claims(claimsWithoutSubject)
|
||||
builder := josejwt.Signed(sig).Claims(claimsWithoutSubject)
|
||||
|
||||
builder = builder.Claims(map[string]any{"some-other-claim": distributedGroups})
|
||||
|
||||
distributedClaimsJwt, err := builder.CompactSerialize()
|
||||
distributedClaimsJwt, err := builder.Serialize()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = w.Write([]byte(distributedClaimsJwt))
|
||||
@@ -172,24 +210,24 @@ func TestController(t *testing.T) {
|
||||
}))
|
||||
|
||||
badMuxInvalidJWKSURI := http.NewServeMux()
|
||||
badOIDCIssuerServerInvalidJWKSURI, _ := tlsserver.TestServerIPv4(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
badOIDCIssuerServerInvalidJWKSURIServer, _ := tlsserver.TestServerIPv4(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
tlsserver.AssertTLS(t, r, ptls.Default)
|
||||
badMuxInvalidJWKSURI.ServeHTTP(w, r)
|
||||
}), tlsserver.RecordTLSHello)
|
||||
badMuxInvalidJWKSURI.Handle("/.well-known/openid-configuration", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, err := fmt.Fprintf(w, `{"issuer": "%s", "jwks_uri": "%s"}`, badOIDCIssuerServerInvalidJWKSURI.URL, "https://.café .com/café/café/café/coffee/jwks.json")
|
||||
_, err := fmt.Fprintf(w, `{"issuer": "%s", "jwks_uri": "%s"}`, badOIDCIssuerServerInvalidJWKSURIServer.URL, "https://.café .com/café/café/café/coffee/jwks.json")
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
|
||||
badMuxInvalidJWKSURIScheme := http.NewServeMux()
|
||||
badOIDCIssuerServerInvalidJWKSURIScheme, _ := tlsserver.TestServerIPv4(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
badOIDCIssuerServerInvalidJWKSURISchemeServer, _ := tlsserver.TestServerIPv4(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
tlsserver.AssertTLS(t, r, ptls.Default)
|
||||
badMuxInvalidJWKSURIScheme.ServeHTTP(w, r)
|
||||
}), tlsserver.RecordTLSHello)
|
||||
badMuxInvalidJWKSURIScheme.Handle("/.well-known/openid-configuration", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, err := fmt.Fprintf(w, `{"issuer": "%s", "jwks_uri": "%s"}`, badOIDCIssuerServerInvalidJWKSURIScheme.URL, "http://.café.com/café/café/café/coffee/jwks.json")
|
||||
_, err := fmt.Fprintf(w, `{"issuer": "%s", "jwks_uri": "%s"}`, badOIDCIssuerServerInvalidJWKSURISchemeServer.URL, "http://.café.com/café/café/café/coffee/jwks.json")
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
|
||||
@@ -204,9 +242,33 @@ func TestController(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
|
||||
// No real OIDC provider should ever be using our hardcoded private key as a signing key, so this should never happen
|
||||
// in real life. Simulating this here just so we can have test coverage for the expected error that the production
|
||||
// code should return in this case.
|
||||
badMuxUsesOurHardcodedPrivateKey := http.NewServeMux()
|
||||
badOIDCIssuerUsesOurHardcodedPrivateKeyServer, _ := tlsserver.TestServerIPv4(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
tlsserver.AssertTLS(t, r, ptls.Default)
|
||||
badMuxUsesOurHardcodedPrivateKey.ServeHTTP(w, r)
|
||||
}), tlsserver.RecordTLSHello)
|
||||
badMuxUsesOurHardcodedPrivateKey.Handle("/.well-known/openid-configuration", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, err := fmt.Fprintf(w, `{"issuer": "%s", "jwks_uri": "%s"}`, badOIDCIssuerUsesOurHardcodedPrivateKeyServer.URL, badOIDCIssuerUsesOurHardcodedPrivateKeyServer.URL+"/jwks.json")
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
badMuxUsesOurHardcodedPrivateKey.Handle("/jwks.json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ecJWK := jose.JSONWebKey{
|
||||
Key: hardcodedPrivateKey,
|
||||
KeyID: goodRSASigningKeyID,
|
||||
Algorithm: string(goodRSASigningAlgo),
|
||||
Use: "sig",
|
||||
}
|
||||
jwks := jose.JSONWebKeySet{
|
||||
Keys: []jose.JSONWebKey{ecJWK.Public()},
|
||||
}
|
||||
require.NoError(t, json.NewEncoder(w).Encode(jwks))
|
||||
}))
|
||||
|
||||
goodIssuer := goodOIDCIssuerServer.URL
|
||||
badIssuerInvalidJWKSURI := badOIDCIssuerServerInvalidJWKSURI.URL
|
||||
badIssuerInvalidJWKSURIScheme := badOIDCIssuerServerInvalidJWKSURIScheme.URL
|
||||
someOtherIssuer := "https://some-other-issuer.com" // placeholder only for tests that don't get far enough to make requests
|
||||
|
||||
nowDoesntMatter := time.Date(1122, time.September, 33, 4, 55, 56, 778899, time.Local)
|
||||
@@ -254,7 +316,6 @@ func TestController(t *testing.T) {
|
||||
Audience: goodAudience,
|
||||
TLS: &authenticationv1alpha1.TLSSpec{CertificateAuthorityData: "invalid base64-encoded data"},
|
||||
}
|
||||
|
||||
invalidIssuerJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: "https://.café .com/café/café/café/coffee",
|
||||
Audience: goodAudience,
|
||||
@@ -265,22 +326,25 @@ func TestController(t *testing.T) {
|
||||
Audience: goodAudience,
|
||||
TLS: conciergetestutil.TLSSpecFromTLSConfig(goodOIDCIssuerServer.TLS),
|
||||
}
|
||||
|
||||
validIssuerURLButDoesNotExistJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: goodIssuer + "/foo/bar/baz/shizzle",
|
||||
Audience: goodAudience,
|
||||
}
|
||||
badIssuerJWKSURIJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: badIssuerInvalidJWKSURI,
|
||||
Issuer: badOIDCIssuerServerInvalidJWKSURIServer.URL,
|
||||
Audience: goodAudience,
|
||||
TLS: conciergetestutil.TLSSpecFromTLSConfig(badOIDCIssuerServerInvalidJWKSURI.TLS),
|
||||
TLS: conciergetestutil.TLSSpecFromTLSConfig(badOIDCIssuerServerInvalidJWKSURIServer.TLS),
|
||||
}
|
||||
badIssuerJWKSURISchemeJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: badIssuerInvalidJWKSURIScheme,
|
||||
Issuer: badOIDCIssuerServerInvalidJWKSURISchemeServer.URL,
|
||||
Audience: goodAudience,
|
||||
TLS: conciergetestutil.TLSSpecFromTLSConfig(badOIDCIssuerServerInvalidJWKSURIScheme.TLS),
|
||||
TLS: conciergetestutil.TLSSpecFromTLSConfig(badOIDCIssuerServerInvalidJWKSURISchemeServer.TLS),
|
||||
}
|
||||
badIssuerUsesOurHardcodedPrivateKeyJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: badOIDCIssuerUsesOurHardcodedPrivateKeyServer.URL,
|
||||
Audience: goodAudience,
|
||||
TLS: conciergetestutil.TLSSpecFromTLSConfig(badOIDCIssuerUsesOurHardcodedPrivateKeyServer.TLS),
|
||||
}
|
||||
|
||||
jwksFetchShouldFailJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: jwksFetchShouldFailServer.URL,
|
||||
Audience: goodAudience,
|
||||
@@ -543,14 +607,14 @@ func TestController(t *testing.T) {
|
||||
Message: "unable to validate; see other conditions for details",
|
||||
}
|
||||
}
|
||||
sadJWKSFetch := func(time metav1.Time, observedGeneration int64) metav1.Condition {
|
||||
sadJWKSFetch := func(msg string, time metav1.Time, observedGeneration int64) metav1.Condition {
|
||||
return metav1.Condition{
|
||||
Type: "JWKSFetchValid",
|
||||
Status: "False",
|
||||
ObservedGeneration: observedGeneration,
|
||||
LastTransitionTime: time,
|
||||
Reason: "InvalidCouldNotFetchJWKS",
|
||||
Message: "could not fetch keys: fetching keys oidc: get keys failed: 404 Not Found 404 page not found\n",
|
||||
Message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,7 +709,8 @@ func TestController(t *testing.T) {
|
||||
}
|
||||
},
|
||||
wantCacheEntries: 1,
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "Sync: changed JWTAuthenticator: loop will update timestamps only on relevant statuses",
|
||||
syncKey: controllerlib.Key{Name: "test-name"},
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
@@ -953,22 +1018,25 @@ func TestController(t *testing.T) {
|
||||
Spec: *someJWTAuthenticatorSpec,
|
||||
},
|
||||
},
|
||||
wantLogs: []map[string]any{{
|
||||
"level": "info",
|
||||
"timestamp": "2099-08-08T13:57:36.123456Z",
|
||||
"logger": "jwtcachefiller-controller",
|
||||
"message": "wrong JWT authenticator type in cache",
|
||||
"actualType": "struct { authenticator.Token }",
|
||||
}, {
|
||||
"level": "info",
|
||||
"timestamp": "2099-08-08T13:57:36.123456Z",
|
||||
"logger": "jwtcachefiller-controller",
|
||||
"message": "added new jwt authenticator",
|
||||
"issuer": goodIssuer,
|
||||
"jwtAuthenticator": map[string]any{
|
||||
"name": "test-name",
|
||||
wantLogs: []map[string]any{
|
||||
{
|
||||
"level": "info",
|
||||
"timestamp": "2099-08-08T13:57:36.123456Z",
|
||||
"logger": "jwtcachefiller-controller",
|
||||
"message": "wrong JWT authenticator type in cache",
|
||||
"actualType": "struct { authenticator.Token }",
|
||||
},
|
||||
}},
|
||||
{
|
||||
"level": "info",
|
||||
"timestamp": "2099-08-08T13:57:36.123456Z",
|
||||
"logger": "jwtcachefiller-controller",
|
||||
"message": "added new jwt authenticator",
|
||||
"issuer": goodIssuer,
|
||||
"jwtAuthenticator": map[string]any{
|
||||
"name": "test-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantActions: func() []coretesting.Action {
|
||||
updateStatusAction := coretesting.NewUpdateAction(jwtAuthenticatorsGVR, "", &authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -1074,7 +1142,8 @@ func TestController(t *testing.T) {
|
||||
}
|
||||
},
|
||||
wantCacheEntries: 0,
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "validateIssuer: parsing error (spec.issuer URL is invalid): loop will fail sync, will write failed and unknown status conditions, but will not enqueue a resync due to user config error",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
@@ -1113,7 +1182,8 @@ func TestController(t *testing.T) {
|
||||
updateStatusAction,
|
||||
}
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "validateIssuer: parsing error (spec.issuer URL has invalid scheme, requires https): loop will fail sync, will write failed and unknown conditions, but will not enqueue a resync due to user config error",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
@@ -1152,7 +1222,8 @@ func TestController(t *testing.T) {
|
||||
updateStatusAction,
|
||||
}
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "validateIssuer: issuer cannot include fragment: loop will fail sync, will write failed and unknown conditions, but will not enqueue a resync due to user config error",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
@@ -1199,7 +1270,8 @@ func TestController(t *testing.T) {
|
||||
updateStatusAction,
|
||||
}
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "validateIssuer: issuer cannot include query params: loop will fail sync, will write failed and unknown conditions, but will not enqueue a resync due to user config error",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
@@ -1246,7 +1318,8 @@ func TestController(t *testing.T) {
|
||||
updateStatusAction,
|
||||
}
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "validateIssuer: issuer cannot include .well-known in path: loop will fail sync, will write failed and unknown conditions, but will not enqueue a resync due to user config error",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
@@ -1293,7 +1366,8 @@ func TestController(t *testing.T) {
|
||||
updateStatusAction,
|
||||
}
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "validateProviderDiscovery: could not perform oidc discovery on provider issuer: loop will fail sync, will write failed and unknown conditions, and will enqueue new sync",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
@@ -1334,7 +1408,8 @@ func TestController(t *testing.T) {
|
||||
}
|
||||
},
|
||||
wantSyncLoopErr: testutil.WantExactErrorString(`could not perform oidc discovery on provider issuer: Get "` + goodIssuer + `/foo/bar/baz/shizzle/.well-known/openid-configuration": tls: failed to verify certificate: x509: certificate signed by unknown authority`),
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "validateProviderDiscovery: excessively long errors truncated: loop will fail sync, will write failed and unknown conditions, and will enqueue new sync",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
@@ -1428,7 +1503,8 @@ func TestController(t *testing.T) {
|
||||
}
|
||||
},
|
||||
wantSyncLoopErr: testutil.WantExactErrorString(`could not parse provider jwks_uri: parse "https://.café .com/café/café/café/coffee/jwks.json": invalid character " " in host name`),
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "validateProviderJWKSURL: invalid scheme, requires 'https': loop will fail sync, will write failed and unknown conditions, and will enqueue new sync",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
@@ -1468,8 +1544,47 @@ func TestController(t *testing.T) {
|
||||
},
|
||||
wantSyncLoopErr: testutil.WantExactErrorString("jwks_uri http://.café.com/café/café/café/coffee/jwks.json has invalid scheme, require 'https'"),
|
||||
},
|
||||
// since this is a hard-coded token we can't do any meaningful testing for this case (and should also never have an error)
|
||||
// {name: "validateJWKSFetch: could not sign tokens"},
|
||||
{
|
||||
name: "validateProviderJWKSURL: remote jwks should not have been able to verify hardcoded test jwt token: loop will fail sync, will write failed and unknown conditions, and will enqueue new sync",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-name",
|
||||
},
|
||||
Spec: *badIssuerUsesOurHardcodedPrivateKeyJWTAuthenticatorSpec,
|
||||
},
|
||||
},
|
||||
syncKey: controllerlib.Key{Name: "test-name"},
|
||||
wantActions: func() []coretesting.Action {
|
||||
updateStatusAction := coretesting.NewUpdateAction(jwtAuthenticatorsGVR, "", &authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-name",
|
||||
},
|
||||
Spec: *badIssuerUsesOurHardcodedPrivateKeyJWTAuthenticatorSpec,
|
||||
Status: authenticationv1alpha1.JWTAuthenticatorStatus{
|
||||
Conditions: conditionstestutil.Replace(
|
||||
allHappyConditionsSuccess(goodIssuer, frozenMetav1Now, 0),
|
||||
[]metav1.Condition{
|
||||
happyIssuerURLValid(frozenMetav1Now, 0),
|
||||
sadReadyCondition(frozenMetav1Now, 0),
|
||||
unknownAuthenticatorValid(frozenMetav1Now, 0),
|
||||
happyDiscoveryURLValid(frozenMetav1Now, 0),
|
||||
sadJWKSFetch("remote jwks should not have been able to verify hardcoded test jwt token",
|
||||
frozenMetav1Now, 0),
|
||||
},
|
||||
),
|
||||
Phase: "Error",
|
||||
},
|
||||
})
|
||||
updateStatusAction.Subresource = "status"
|
||||
return []coretesting.Action{
|
||||
coretesting.NewListAction(jwtAuthenticatorsGVR, jwtAUthenticatorGVK, "", metav1.ListOptions{}),
|
||||
coretesting.NewWatchAction(jwtAuthenticatorsGVR, "", metav1.ListOptions{}),
|
||||
updateStatusAction,
|
||||
}
|
||||
},
|
||||
wantSyncLoopErr: testutil.WantExactErrorString("remote jwks should not have been able to verify hardcoded test jwt token"),
|
||||
},
|
||||
{
|
||||
name: "validateJWKSFetch: could not fetch keys: loop will fail sync, will write failed and unknown status conditions, and will enqueue a resync",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
@@ -1494,7 +1609,8 @@ func TestController(t *testing.T) {
|
||||
happyIssuerURLValid(frozenMetav1Now, 0),
|
||||
sadReadyCondition(frozenMetav1Now, 0),
|
||||
unknownAuthenticatorValid(frozenMetav1Now, 0),
|
||||
sadJWKSFetch(frozenMetav1Now, 0),
|
||||
sadJWKSFetch("could not fetch keys: fetching keys oidc: get keys failed: 404 Not Found 404 page not found\n",
|
||||
frozenMetav1Now, 0),
|
||||
},
|
||||
),
|
||||
Phase: "Error",
|
||||
@@ -1783,13 +1899,13 @@ func TestController(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
wellKnownClaims := jwt.Claims{
|
||||
wellKnownClaims := josejwt.Claims{
|
||||
Issuer: goodIssuer,
|
||||
Subject: goodSubject,
|
||||
Audience: []string{goodAudience},
|
||||
Expiry: jwt.NewNumericDate(time.Now().Add(time.Hour)),
|
||||
NotBefore: jwt.NewNumericDate(time.Now().Add(-time.Hour)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now().Add(-time.Hour)),
|
||||
Expiry: josejwt.NewNumericDate(time.Now().Add(time.Hour)),
|
||||
NotBefore: josejwt.NewNumericDate(time.Now().Add(-time.Hour)),
|
||||
IssuedAt: josejwt.NewNumericDate(time.Now().Add(-time.Hour)),
|
||||
}
|
||||
var groups any
|
||||
username := goodUsername
|
||||
@@ -1860,7 +1976,7 @@ func testTableForAuthenticateTokenTests(
|
||||
issuer string,
|
||||
) []struct {
|
||||
name string
|
||||
jwtClaims func(wellKnownClaims *jwt.Claims, groups *any, username *string)
|
||||
jwtClaims func(wellKnownClaims *josejwt.Claims, groups *any, username *string)
|
||||
jwtSignature func(key *any, algo *jose.SignatureAlgorithm, kid *string)
|
||||
wantResponse *authenticator.Response
|
||||
wantAuthenticated bool
|
||||
@@ -1869,7 +1985,7 @@ func testTableForAuthenticateTokenTests(
|
||||
} {
|
||||
tests := []struct {
|
||||
name string
|
||||
jwtClaims func(wellKnownClaims *jwt.Claims, groups *any, username *string)
|
||||
jwtClaims func(wellKnownClaims *josejwt.Claims, groups *any, username *string)
|
||||
jwtSignature func(key *any, algo *jose.SignatureAlgorithm, kid *string)
|
||||
wantResponse *authenticator.Response
|
||||
wantAuthenticated bool
|
||||
@@ -1901,7 +2017,7 @@ func testTableForAuthenticateTokenTests(
|
||||
},
|
||||
{
|
||||
name: "good token with groups as array",
|
||||
jwtClaims: func(_ *jwt.Claims, groups *any, username *string) {
|
||||
jwtClaims: func(_ *josejwt.Claims, groups *any, username *string) {
|
||||
*groups = []string{group0, group1}
|
||||
},
|
||||
wantResponse: &authenticator.Response{
|
||||
@@ -1914,7 +2030,7 @@ func testTableForAuthenticateTokenTests(
|
||||
},
|
||||
{
|
||||
name: "good token with good distributed groups",
|
||||
jwtClaims: func(claims *jwt.Claims, groups *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, groups *any, username *string) {
|
||||
},
|
||||
distributedGroupsClaimURL: issuer + "/claim_source",
|
||||
wantResponse: &authenticator.Response{
|
||||
@@ -1927,21 +2043,21 @@ func testTableForAuthenticateTokenTests(
|
||||
},
|
||||
{
|
||||
name: "distributed groups returns a 404",
|
||||
jwtClaims: func(claims *jwt.Claims, groups *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, groups *any, username *string) {
|
||||
},
|
||||
distributedGroupsClaimURL: issuer + "/not_found_claim_source",
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: could not expand distributed claims: while getting distributed claim "` + expectedGroupsClaim + `": error while getting distributed claim JWT: 404 Not Found`),
|
||||
},
|
||||
{
|
||||
name: "distributed groups doesn't return the right claim",
|
||||
jwtClaims: func(claims *jwt.Claims, groups *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, groups *any, username *string) {
|
||||
},
|
||||
distributedGroupsClaimURL: issuer + "/wrong_claim_source",
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: could not expand distributed claims: jwt returned by distributed claim endpoint "` + issuer + `/wrong_claim_source" did not contain claim: `),
|
||||
},
|
||||
{
|
||||
name: "good token with groups as string",
|
||||
jwtClaims: func(_ *jwt.Claims, groups *any, username *string) {
|
||||
jwtClaims: func(_ *josejwt.Claims, groups *any, username *string) {
|
||||
*groups = group0
|
||||
},
|
||||
wantResponse: &authenticator.Response{
|
||||
@@ -1954,7 +2070,7 @@ func testTableForAuthenticateTokenTests(
|
||||
},
|
||||
{
|
||||
name: "good token with nbf unset",
|
||||
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.NotBefore = nil
|
||||
},
|
||||
wantResponse: &authenticator.Response{
|
||||
@@ -1966,14 +2082,14 @@ func testTableForAuthenticateTokenTests(
|
||||
},
|
||||
{
|
||||
name: "bad token with groups as map",
|
||||
jwtClaims: func(_ *jwt.Claims, groups *any, username *string) {
|
||||
jwtClaims: func(_ *josejwt.Claims, groups *any, username *string) {
|
||||
*groups = map[string]string{"not an array": "or a string"}
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString("oidc: parse groups claim \"" + expectedGroupsClaim + "\": json: cannot unmarshal object into Go value of type string"),
|
||||
},
|
||||
{
|
||||
name: "bad token with wrong issuer",
|
||||
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.Issuer = "wrong-issuer"
|
||||
},
|
||||
wantResponse: nil,
|
||||
@@ -1981,42 +2097,42 @@ func testTableForAuthenticateTokenTests(
|
||||
},
|
||||
{
|
||||
name: "bad token with no audience",
|
||||
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.Audience = nil
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: expected audience "some-audience" got \[\]`),
|
||||
},
|
||||
{
|
||||
name: "bad token with wrong audience",
|
||||
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.Audience = []string{"wrong-audience"}
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: expected audience "some-audience" got \["wrong-audience"\]`),
|
||||
},
|
||||
{
|
||||
name: "bad token with nbf in the future",
|
||||
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
|
||||
claims.NotBefore = jwt.NewNumericDate(time.Date(3020, 2, 3, 4, 5, 6, 7, time.UTC))
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.NotBefore = josejwt.NewNumericDate(time.Date(3020, 2, 3, 4, 5, 6, 7, time.UTC))
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: current time .* before the nbf \(not before\) time: 3020-.*`),
|
||||
},
|
||||
{
|
||||
name: "bad token with exp in past",
|
||||
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
|
||||
claims.Expiry = jwt.NewNumericDate(time.Date(1, 2, 3, 4, 5, 6, 7, time.UTC))
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.Expiry = josejwt.NewNumericDate(time.Date(1, 2, 3, 4, 5, 6, 7, time.UTC))
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: token is expired \(Token Expiry: .+`),
|
||||
},
|
||||
{
|
||||
name: "bad token without exp",
|
||||
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.Expiry = nil
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: token is expired \(Token Expiry: .+`),
|
||||
},
|
||||
{
|
||||
name: "token does not have username claim",
|
||||
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
*username = ""
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: parse username claims "` + expectedUsernameClaim + `": claim not present`),
|
||||
@@ -2051,7 +2167,7 @@ func createJWT(
|
||||
signingKey any,
|
||||
signingAlgo jose.SignatureAlgorithm,
|
||||
kid string,
|
||||
claims *jwt.Claims,
|
||||
claims *josejwt.Claims,
|
||||
groupsClaim string,
|
||||
groupsValue any,
|
||||
distributedGroupsClaimURL string,
|
||||
@@ -2066,7 +2182,7 @@ func createJWT(
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
builder := jwt.Signed(sig).Claims(claims)
|
||||
builder := josejwt.Signed(sig).Claims(claims)
|
||||
if groupsValue != nil {
|
||||
builder = builder.Claims(map[string]any{groupsClaim: groupsValue})
|
||||
}
|
||||
@@ -2077,7 +2193,7 @@ func createJWT(
|
||||
if usernameValue != "" {
|
||||
builder = builder.Claims(map[string]any{usernameClaim: usernameValue})
|
||||
}
|
||||
jwt, err := builder.CompactSerialize()
|
||||
jwt, err := builder.Serialize()
|
||||
require.NoError(t, err)
|
||||
|
||||
return jwt
|
||||
|
||||
27
internal/controller/authenticator/jwtcachefiller/testdata/test.key
vendored
Normal file
27
internal/controller/authenticator/jwtcachefiller/testdata/test.key
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAtZBQ4XhDQDayJhzbl6Bimq4Ca5KpNHdhveYzbYNtRUzDDRZ7
|
||||
1GSbduxI2jHWVw7/F2lppypb3SxzJj1fEc5YnyFgso2VnihwVwR7qvuVDwO1ZIWI
|
||||
9G6e0y8/oy+Z2f3zqTEwd5LIdo1PaWIJMKwNIvGZNtoqdvc0R2wm9f4ygdhxN4+n
|
||||
0XRx6NzAVvIonYE4p+93MXPW8+gWfHVXmF6dGNDZCbWFayHP6ZLri1p9S+LzlwhV
|
||||
av9jE30RdnjXo8yL5L4D31qTct+HXgXq+p/g2Tnu58hyNr1TEzEWAhVRB63KTk/4
|
||||
O+0LAxfxt28HGdrMmGP2Qid/PqGvL5JHj7tzTQIDAQABAoIBAHMtN4Gwbsj/aYev
|
||||
6sWHIsYI+NQQ13HHAaQbsigYpWq+xUU6LBeSMuUAAz8XOmdDxiKt5i37OwdVOT7a
|
||||
08JR6foYjGT4WB9ae9lXqLPQoMBDlABOjZCx0+MYKAB3I9wbs0RzRdG0taIvBl9N
|
||||
p5LOsg6mwJEBWMrbCrj8LMMEHDotaBSqD+A2vAsP9Z6g1+Eh+T8eRRGKmNlPkfmW
|
||||
V7WplhIL6JdWI/+LsjCsWkOjMI8hndGWuXKt3wBmAAf8W0l/k3jAdR6C4gX2z5rn
|
||||
nLFYjlHD/mZ3ii3SG7iZOVRpLiwCSA/lIoUXl7we2uGKkbP7WKuZfSQkJ18A5X2r
|
||||
yeLjPQECgYEA0f05bXYgHRcc5fdn5mCjQGgdTvP2MDkI3pMpWgi6AGhjP1LXF/I/
|
||||
MK4v061wWKqIlc6g/Hwi1yClap1c3qLCbvvonFTLwvRM23OTcHAAT3/iXZ4jhmFt
|
||||
96KIeVlgEUFS6tkhxXi/H0lwpK18QDaxSwxJRM3A35jPUTyTU/ADKaECgYEA3Vik
|
||||
5TTaNdjt5WRQysEGQENSTDPJ0c9M8/KnknEa7Xr6vkI81EVMRwCT59ll8tAD0fvB
|
||||
am/YQ0xn8tJh9yuCjSyxHJ7qSjPDnZUbOgPo7r82iWDb7hpsFFnuUUddMMRxe8ag
|
||||
iCTEDXicwLcB8RnioICZyI+GEVxlT6jsW69N4i0CgYEAoCOn9vU9ulGVBT9u6f7K
|
||||
oOSFbV+ZYN8uB2ddAr9i8cqp3XHUfPuN+xbrfFdpNQUgUnaYyNP2Ue8glzTYzSR8
|
||||
eNz9YLM+DTf3oOf8CaQwaHBTdieSWfnVPiOiRkDFhYM2s8jQ+2KBBmAgWkW/Ws0a
|
||||
2evNuH3c1+gWOpKinEGOd+ECgYEAlLYcuz3iKXFgi9D1EvPSflR8s2PMAWF0gyWR
|
||||
firte4Y3dqJL+hXA5Kc3t/pwq00kc+zgCuGv+68W26aLWSPrZ2wSZndCU64pi/ME
|
||||
wtqjodvoCS6BNJyd5qJxIjx/GOeykwVlD3McISzarAOIk3LftxQPvhbnbTyVeIq2
|
||||
mfbSrdUCgYEAmlxEU8VYH4J1HGROcpBGWLFzDjMFKX1LSUFMchJ+Fa1bup3w1upW
|
||||
Zuwm9JtgxuaADyzYFESfzXOaxsW7Z320V/baAqigpoKC1Cyr1KXGKZfOcMLyAKK9
|
||||
q88zOKCZ083T4E/6h7TmSPck6SrqF9TyqlHsaSCbQxe6JhSdIOnGYZA=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package supervisorconfig
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
corev1informers "k8s.io/client-go/informers/core/v1"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
|
||||
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
|
||||
"go.pinniped.dev/internal/constable"
|
||||
@@ -64,7 +64,7 @@ func NewPinnipedSession(
|
||||
|
||||
pinnipedSession := &psession.PinnipedSession{
|
||||
Fosite: &openid.DefaultSession{
|
||||
Claims: &jwt.IDTokenClaims{
|
||||
Claims: &fositejwt.IDTokenClaims{
|
||||
Subject: c.UpstreamIdentity.DownstreamSubject,
|
||||
RequestedAt: now,
|
||||
AuthTime: now,
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
|
||||
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
|
||||
"go.pinniped.dev/internal/federationdomain/csrftoken"
|
||||
@@ -360,7 +360,7 @@ func generateUpstreamAuthorizeRequestState(
|
||||
now := time.Now()
|
||||
_, err := oauthHelper.NewAuthorizeResponse(r.Context(), authorizeRequester, &psession.PinnipedSession{
|
||||
Fosite: &openid.DefaultSession{
|
||||
Claims: &jwt.IDTokenClaims{
|
||||
Claims: &fositejwt.IDTokenClaims{
|
||||
// Temporary claim values to allow `NewAuthorizeResponse` to perform other OIDC validations.
|
||||
Subject: "none",
|
||||
AuthTime: now,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package jwks
|
||||
@@ -6,7 +6,7 @@ package jwks
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
)
|
||||
|
||||
type DynamicJWKSProvider interface {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.pinniped.dev/internal/here"
|
||||
|
||||
@@ -22,13 +22,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
josejwt "github.com/go-jose/go-jose/v3/jwt"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
josejwt "github.com/go-jose/go-jose/v4/jwt"
|
||||
"github.com/ory/fosite"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
fositepkce "github.com/ory/fosite/handler/pkce"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
@@ -1716,7 +1716,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
|
||||
|
||||
claimsOfFirstIDToken := map[string]any{}
|
||||
originalIDToken := parsedAuthcodeExchangeResponseBody["id_token"].(string)
|
||||
firstIDTokenDecoded, _ := josejwt.ParseSigned(originalIDToken)
|
||||
firstIDTokenDecoded, _ := josejwt.ParseSigned(originalIDToken, []jose.SignatureAlgorithm{jose.ES256})
|
||||
err = firstIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfFirstIDToken)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1725,7 +1725,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
|
||||
require.Equal(t, "urn:ietf:params:oauth:token-type:jwt", parsedResponseBody["issued_token_type"])
|
||||
|
||||
// Parse the returned token.
|
||||
parsedJWT, err := jose.ParseSigned(parsedResponseBody["access_token"].(string))
|
||||
parsedJWT, err := jose.ParseSigned(parsedResponseBody["access_token"].(string), []jose.SignatureAlgorithm{jose.ES256})
|
||||
require.NoError(t, err)
|
||||
var tokenClaims map[string]any
|
||||
require.NoError(t, json.Unmarshal(parsedJWT.UnsafePayloadWithoutVerification(), &tokenClaims))
|
||||
@@ -4831,12 +4831,12 @@ func TestRefreshGrant(t *testing.T) {
|
||||
|
||||
if wantIDToken {
|
||||
var claimsOfFirstIDToken map[string]any
|
||||
firstIDTokenDecoded, _ := josejwt.ParseSigned(parsedAuthcodeExchangeResponseBody["id_token"].(string))
|
||||
firstIDTokenDecoded, _ := josejwt.ParseSigned(parsedAuthcodeExchangeResponseBody["id_token"].(string), []jose.SignatureAlgorithm{jose.ES256})
|
||||
err := firstIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfFirstIDToken)
|
||||
require.NoError(t, err)
|
||||
|
||||
var claimsOfSecondIDToken map[string]any
|
||||
secondIDTokenDecoded, _ := josejwt.ParseSigned(parsedRefreshResponseBody["id_token"].(string))
|
||||
secondIDTokenDecoded, _ := josejwt.ParseSigned(parsedRefreshResponseBody["id_token"].(string), []jose.SignatureAlgorithm{jose.ES256})
|
||||
err = secondIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfSecondIDToken)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -5145,7 +5145,7 @@ func simulateAuthEndpointHavingAlreadyRun(
|
||||
ctx := context.Background()
|
||||
session := &psession.PinnipedSession{
|
||||
Fosite: &openid.DefaultSession{
|
||||
Claims: &jwt.IDTokenClaims{
|
||||
Claims: &fositejwt.IDTokenClaims{
|
||||
Subject: goodSubject,
|
||||
RequestedAt: goodRequestedAtTime,
|
||||
AuthTime: goodAuthTime,
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
@@ -14,10 +14,10 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
|
||||
@@ -103,7 +103,7 @@ func TestDynamicOpenIDConnectECDSAStrategy(t *testing.T) {
|
||||
ID: clientID,
|
||||
},
|
||||
Session: &openid.DefaultSession{
|
||||
Claims: &jwt.IDTokenClaims{
|
||||
Claims: &fositejwt.IDTokenClaims{
|
||||
Subject: goodSubject,
|
||||
},
|
||||
Subject: goodSubject,
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -334,8 +334,8 @@ func TestReadFromSecret(t *testing.T) {
|
||||
Fosite: &openid.DefaultSession{
|
||||
Username: "snorlax",
|
||||
Subject: "panda",
|
||||
Claims: &jwt.IDTokenClaims{JTI: "xyz"},
|
||||
Headers: &jwt.Headers{Extra: map[string]any{"myheader": "foo"}},
|
||||
Claims: &fositejwt.IDTokenClaims{JTI: "xyz"},
|
||||
Headers: &fositejwt.Headers{Extra: map[string]any{"myheader": "foo"}},
|
||||
},
|
||||
Custom: &psession.CustomSessionData{
|
||||
Username: "fake-username",
|
||||
|
||||
@@ -15,12 +15,12 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
oldjosev3 "github.com/go-jose/go-jose/v3" // we need to use the same version of jose that fosite uses when fuzzing fosite objects
|
||||
fuzz "github.com/google/gofuzz"
|
||||
"github.com/ory/fosite"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -343,7 +343,7 @@ func TestFuzzAndJSONNewValidEmptyAuthorizeCodeSession(t *testing.T) {
|
||||
},
|
||||
// JWK contains an any Key that we need to handle
|
||||
// this is safe because JWK explicitly implements JSON marshalling and unmarshalling
|
||||
func(jwk *jose.JSONWebKey, c fuzz.Continue) {
|
||||
func(jwk *oldjosev3.JSONWebKey, c fuzz.Continue) {
|
||||
key, _, err := ed25519.GenerateKey(c)
|
||||
require.NoError(t, err)
|
||||
jwk.Key = key
|
||||
@@ -470,8 +470,8 @@ func TestReadFromSecret(t *testing.T) {
|
||||
Fosite: &openid.DefaultSession{
|
||||
Username: "snorlax",
|
||||
Subject: "panda",
|
||||
Claims: &jwt.IDTokenClaims{JTI: "xyz"},
|
||||
Headers: &jwt.Headers{Extra: map[string]any{"myheader": "foo"}},
|
||||
Claims: &fositejwt.IDTokenClaims{JTI: "xyz"},
|
||||
Headers: &fositejwt.Headers{Extra: map[string]any{"myheader": "foo"}},
|
||||
},
|
||||
Custom: &psession.CustomSessionData{
|
||||
Username: "fake-username",
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -391,8 +391,8 @@ func TestReadFromSecret(t *testing.T) {
|
||||
Fosite: &openid.DefaultSession{
|
||||
Username: "snorlax",
|
||||
Subject: "panda",
|
||||
Claims: &jwt.IDTokenClaims{JTI: "xyz"},
|
||||
Headers: &jwt.Headers{Extra: map[string]any{"myheader": "foo"}},
|
||||
Claims: &fositejwt.IDTokenClaims{JTI: "xyz"},
|
||||
Headers: &fositejwt.Headers{Extra: map[string]any{"myheader": "foo"}},
|
||||
},
|
||||
Custom: &psession.CustomSessionData{
|
||||
Username: "fake-username",
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/mohae/deepcopy"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
@@ -157,8 +157,8 @@ func (s *GitHubSessionData) Clone() *GitHubSessionData {
|
||||
func NewPinnipedSession() *PinnipedSession {
|
||||
return &PinnipedSession{
|
||||
Fosite: &openid.DefaultSession{
|
||||
Claims: &jwt.IDTokenClaims{},
|
||||
Headers: &jwt.Headers{},
|
||||
Claims: &fositejwt.IDTokenClaims{},
|
||||
Headers: &fositejwt.Headers{},
|
||||
},
|
||||
Custom: &CustomSessionData{},
|
||||
}
|
||||
@@ -192,10 +192,10 @@ func (s *PinnipedSession) GetSubject() string {
|
||||
return s.Fosite.GetSubject()
|
||||
}
|
||||
|
||||
func (s *PinnipedSession) IDTokenHeaders() *jwt.Headers {
|
||||
func (s *PinnipedSession) IDTokenHeaders() *fositejwt.Headers {
|
||||
return s.Fosite.IDTokenHeaders()
|
||||
}
|
||||
|
||||
func (s *PinnipedSession) IDTokenClaims() *jwt.IDTokenClaims {
|
||||
func (s *PinnipedSession) IDTokenClaims() *fositejwt.IDTokenClaims {
|
||||
return s.Fosite.IDTokenClaims()
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"testing"
|
||||
|
||||
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ func newStaticKeySet(publicKey crypto.PublicKey) coreosoidc.KeySet {
|
||||
}
|
||||
|
||||
func (s *staticKeySet) VerifySignature(_ context.Context, jwt string) ([]byte, error) {
|
||||
jws, err := jose.ParseSigned(jwt)
|
||||
jws, err := jose.ParseSigned(jwt, []jose.SignatureAlgorithm{jose.ES256})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oidc: malformed jwt: %w", err)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"unsafe"
|
||||
|
||||
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
"golang.org/x/oauth2"
|
||||
@@ -1413,7 +1413,7 @@ func mockVerifier() *coreosoidc.IDTokenVerifier {
|
||||
mockKeySet.EXPECT().VerifySignature(gomock.Any(), gomock.Any()).
|
||||
AnyTimes().
|
||||
DoAndReturn(func(ctx context.Context, jwt string) ([]byte, error) {
|
||||
jws, err := jose.ParseSigned(jwt)
|
||||
jws, err := jose.ParseSigned(jwt, []jose.SignatureAlgorithm{jose.ES256, jose.RS256})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/sync/errgroup"
|
||||
@@ -193,7 +193,7 @@ func TestCLILoginOIDC_Browser(t *testing.T) {
|
||||
|
||||
// Assert some properties about the token, which should be a valid JWT.
|
||||
require.NotEmpty(t, credOutput.Status.Token)
|
||||
jws, err := jose.ParseSigned(credOutput.Status.Token)
|
||||
jws, err := jose.ParseSigned(credOutput.Status.Token, []jose.SignatureAlgorithm{jose.ES256, jose.RS256})
|
||||
require.NoError(t, err)
|
||||
claims := map[string]any{}
|
||||
require.NoError(t, json.Unmarshal(jws.UnsafePayloadWithoutVerification(), &claims))
|
||||
|
||||
@@ -10,7 +10,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3/jwt"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
josejwt "github.com/go-jose/go-jose/v4/jwt"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -219,7 +220,7 @@ func safeDerefStringPtr(s *string) string {
|
||||
func getJWTSubAndGroupsClaims(t *testing.T, jwtToken string) (string, []string) {
|
||||
t.Helper()
|
||||
|
||||
token, err := jwt.ParseSigned(jwtToken)
|
||||
token, err := josejwt.ParseSigned(jwtToken, []jose.SignatureAlgorithm{jose.ES256, jose.RS256})
|
||||
require.NoError(t, err)
|
||||
|
||||
var claims struct {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
Reference in New Issue
Block a user