Skip to content

Commit

Permalink
CRDB-28040 : JWKS fetch from jwks_uri - test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
BabuSrithar committed Jan 29, 2024
1 parent 6ca2aab commit 9ceb3a2
Show file tree
Hide file tree
Showing 6 changed files with 308 additions and 6 deletions.
4 changes: 4 additions & 0 deletions pkg/ccl/jwtauthccl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ go_test(
"main_test.go",
"settings_test.go",
],
data = glob(["testdata/**"]),
embed = [":jwtauthccl"],
exec_properties = select({
"//build/toolchains:is_heavy": {"Pool": "heavy"},
Expand All @@ -49,12 +50,15 @@ go_test(
"//pkg/security/username",
"//pkg/server",
"//pkg/sql/pgwire/identmap",
"//pkg/testutils",
"//pkg/testutils/serverutils",
"//pkg/testutils/testcluster",
"//pkg/util/leaktest",
"//pkg/util/log",
"//pkg/util/randutil",
"//pkg/util/timeutil",
"@com_github_cockroachdb_errors//:errors",
"@com_github_cockroachdb_errors//oserror",
"@com_github_lestrrat_go_jwx//jwa",
"@com_github_lestrrat_go_jwx//jwk",
"@com_github_lestrrat_go_jwx//jwt",
Expand Down
196 changes: 191 additions & 5 deletions pkg/ccl/jwtauthccl/authentication_jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,23 @@ import (
"crypto/rand"
"crypto/rsa"
"encoding/json"
"os"
"strings"
"testing"
"time"

"github.com/cockroachdb/cockroach/pkg/base"
"github.com/cockroachdb/cockroach/pkg/security/username"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/identmap"
"github.com/cockroachdb/cockroach/pkg/testutils"
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
"github.com/cockroachdb/cockroach/pkg/util/log"
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
"github.com/cockroachdb/errors"
"github.com/cockroachdb/errors/oserror"
"github.com/lestrrat-go/jwx/jwa"
jwk "github.com/lestrrat-go/jwx/jwk"
"github.com/lestrrat-go/jwx/jwk"
"github.com/lestrrat-go/jwx/jwt"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -168,7 +172,7 @@ func TestJWTSingleKey(t *testing.T) {

// When no JWKS is specified the JWKS fetch should be attempted and fail for configured issuer.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(invalidUsername), token, identMap)
require.ErrorContains(t, err, "JWT authentication: invalid token")
require.ErrorContains(t, err, "JWT authentication: unable to validate token")

// Set the JWKS cluster setting.
JWTAuthJWKS.Override(ctx, &s.ClusterSettings().SV, jwkPublicKey)
Expand Down Expand Up @@ -204,7 +208,7 @@ func TestJWTSingleKeyWithoutKeyAlgorithm(t *testing.T) {

// When no JWKS is specified the JWKS fetch should be attempted and fail for configured issuer.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(invalidUsername), token, identMap)
require.ErrorContains(t, err, "JWT authentication: invalid token")
require.ErrorContains(t, err, "JWT authentication: unable to validate token")

// Set the JWKS cluster setting.
JWTAuthJWKS.Override(ctx, &s.ClusterSettings().SV, jwkPublicKey)
Expand Down Expand Up @@ -241,7 +245,7 @@ func TestJWTMultiKey(t *testing.T) {

// When the JWKS is set not to include the key used to sign the token, the jwks fetch should be attempted and fail.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(invalidUsername), token, identMap)
require.ErrorContains(t, err, "JWT authentication: invalid token")
require.ErrorContains(t, err, "JWT authentication: unable to validate token")

// Set both jwk1 and jwk2 to be valid signing keys.
JWTAuthJWKS.Override(ctx, &s.ClusterSettings().SV, serializePublicKeySet(t, keySet))
Expand Down Expand Up @@ -298,7 +302,7 @@ func TestKeyIdMismatch(t *testing.T) {

// When JWKS is set not to include the key with keyId used to sign the token, jwks fetch should be attempted and fail.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(invalidUsername), token, identMap)
require.ErrorContains(t, err, "JWT authentication: invalid token")
require.ErrorContains(t, err, "JWT authentication: unable to validate token")

// Reset the key id and regenerate the token.
require.NoError(t, key.Set(jwk.KeyIDKey, keyID1))
Expand Down Expand Up @@ -604,3 +608,185 @@ func TestAudienceCheck(t *testing.T) {
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(username1), token, identMap)
require.NoError(t, err)
}

// mockGetHttpResponseWithLocalFileContent is a mock function for getHttpResponse. This is used to intercept the call to
// getHttpResponse and return the content of a local file instead of making a http call.
var mockGetHttpResponseWithLocalFileContent = func(ctx context.Context, url string) ([]byte, error) {
// remove https:// and replace / with _ in the url to get the testdata file name
fileName := "testdata/" + strings.ReplaceAll(strings.ReplaceAll(url, "https://", ""), "/", "_")
// read content of the file as a byte array
byteValue, err := os.ReadFile(fileName)
if err != nil {
if oserror.IsNotExist(err) {
// return http status 404 if the file does not exist
return nil, errors.New("404 Not Found")
}
return nil, err
}
return byteValue, nil
}

// createJWKSFromFile creates a jwk set from a local file. The file used by this function is expected to contain both
// private and public keys.
func createJWKSFromFile(t *testing.T, fileName string) jwk.Set {
byteValue, err := os.ReadFile(fileName)
require.NoError(t, err)
jwkSet, err := jwk.Parse(byteValue)
if err != nil {
return nil
}
return jwkSet
}

// test that jwks url is used when jwks cluster setting is not configured.
func Test_JWKSFallBackWhenJWKSClusterSettingNotConfigured(t *testing.T) {
defer leaktest.AfterTest(t)()
// Intercept the call to getHttpResponse and return the mockGetHttpResponse
restoreHook := testutils.TestingHook(&getHttpResponse, mockGetHttpResponseWithLocalFileContent)
defer func() {
restoreHook()
}()
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)
ctx := context.Background()
s := serverutils.StartServerOnly(t, base.TestServerArgs{})
defer s.Stopper().Stop(ctx)
identMapString := ""
identMap, err := identmap.From(strings.NewReader(identMapString))
require.NoError(t, err)

// Create key from a file. This key will be used to sign the token.
// Matching public key available in jwks url is used to verify token.
keySet := createJWKSFromFile(t, "testdata/www.idp1apis.com_oauth2_v3_certs_private")
key, _ := keySet.Get(0)
validIssuer := "https://accounts.idp1.com"
token := createJWT(t, username1, audience1, validIssuer, timeutil.Now().Add(time.Hour), key, jwa.RS256, "", "")

// Make sure jwt auth is enabled and accepts jwk1 or jwk2 as valid signing keys.
JWTAuthEnabled.Override(ctx, &s.ClusterSettings().SV, true)
//JWTAuthJWKS.Override(ctx, &s.ClusterSettings().SV, serializePublicKeySet(t, keySet))
JWTAuthIssuers.Override(ctx, &s.ClusterSettings().SV, validIssuer)

// Set audience field to audience2.
JWTAuthAudience.Override(ctx, &s.ClusterSettings().SV, audience2)

verifier := ConfigureJWTAuth(ctx, s.AmbientCtx(), s.ClusterSettings(), s.StorageClusterID())

// Validation fails with an audience error when the audience in the token doesn't match the cluster's audience.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(username1), token, identMap)
require.ErrorContains(t, err, "JWT authentication: invalid audience")

// Update the audience field to "test_cluster".
JWTAuthAudience.Override(ctx, &s.ClusterSettings().SV, audience1)

// Validation passes the audience check now that they match.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(username1), token, identMap)
require.NoError(t, err)

// Set audience field to both audience1 and audience2.
JWTAuthAudience.Override(ctx, &s.ClusterSettings().SV, "[\""+audience2+"\",\""+audience1+"\"]")
// Validation passes the audience check now that both audiences are accepted.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(username1), token, identMap)
require.NoError(t, err)
}

// test that jwks url is used when jwks cluster setting is configured but does not have the kid required by token.
func Test_JWKSFallBackWhenJWKSClusterSettingConfiguredButFails(t *testing.T) {
defer leaktest.AfterTest(t)()
// Intercept the call to getHttpResponse and return the mockGetHttpResponse
restoreHook := testutils.TestingHook(&getHttpResponse, mockGetHttpResponseWithLocalFileContent)
defer func() {
restoreHook()
}()
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)
ctx := context.Background()
s := serverutils.StartServerOnly(t, base.TestServerArgs{})
defer s.Stopper().Stop(ctx)
identMapString := ""
identMap, err := identmap.From(strings.NewReader(identMapString))
require.NoError(t, err)

// Create key from a file. This key will be used to sign the token.
// Matching public key available in jwks url is used to verify token.
keySetUsedForSigning := createJWKSFromFile(t, "testdata/www.idp1apis.com_oauth2_v3_certs_private")
key, _ := keySetUsedForSigning.Get(0)
validIssuer := "https://accounts.idp1.com"
token := createJWT(t, username1, audience1, validIssuer, timeutil.Now().Add(time.Hour), key, jwa.RS256, "", "")

// Make sure jwt auth is enabled and accepts jwk1 or jwk2 as valid signing keys.
JWTAuthEnabled.Override(ctx, &s.ClusterSettings().SV, true)

// Configure cluster setting with a key that is not used for signing.
keySetNotUsedForSigning, _, _ := createJWKS(t)
JWTAuthJWKS.Override(ctx, &s.ClusterSettings().SV, serializePublicKeySet(t, keySetNotUsedForSigning))
JWTAuthIssuers.Override(ctx, &s.ClusterSettings().SV, validIssuer)

// Set audience field to audience2.
JWTAuthAudience.Override(ctx, &s.ClusterSettings().SV, audience2)

verifier := ConfigureJWTAuth(ctx, s.AmbientCtx(), s.ClusterSettings(), s.StorageClusterID())

// Validation fails with an audience error when the audience in the token doesn't match the cluster's audience.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(username1), token, identMap)
require.ErrorContains(t, err, "JWT authentication: invalid audience")

// Update the audience field to "test_cluster".
JWTAuthAudience.Override(ctx, &s.ClusterSettings().SV, audience1)

// Validation passes the audience check now that they match.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(username1), token, identMap)
require.NoError(t, err)

// Set audience field to both audience1 and audience2.
JWTAuthAudience.Override(ctx, &s.ClusterSettings().SV, "[\""+audience2+"\",\""+audience1+"\"]")
// Validation passes the audience check now that both audiences are accepted.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(username1), token, identMap)
require.NoError(t, err)
}

// Test that jwks url is not used when jwks cluster setting is configured and has the kid required by token.
func Test_NoFallbackWhenSameKIDExitsInClusterSetting(t *testing.T) {
defer leaktest.AfterTest(t)()
// Intercept the call to getHttpResponse and return the mockGetHttpResponse
restoreHook := testutils.TestingHook(&getHttpResponse, mockGetHttpResponseWithLocalFileContent)
defer func() {
restoreHook()
}()
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)
ctx := context.Background()
s := serverutils.StartServerOnly(t, base.TestServerArgs{})
defer s.Stopper().Stop(ctx)
identMapString := ""
identMap, err := identmap.From(strings.NewReader(identMapString))
require.NoError(t, err)

// Create keyUsedForSigning from a file. This keyUsedForSigning will be used to sign the token.
// Matching public keyUsedForSigning available in jwks url is used to verify token.
keySetUsedForSigning := createJWKSFromFile(t, "testdata/www.idp1apis.com_oauth2_v3_certs_private")
keyUsedForSigning, _ := keySetUsedForSigning.Get(0)
validIssuer := "https://accounts.idp1.com"
token := createJWT(t, username1, audience1, validIssuer, timeutil.Now().Add(time.Hour), keyUsedForSigning, jwa.RS256, "", "")

// Make sure jwt auth is enabled and accepts jwk1 or jwk2 as valid signing keys.
JWTAuthEnabled.Override(ctx, &s.ClusterSettings().SV, true)

// Configure cluster setting with a keyUsedForSigning that is not used for signing.
keySetNotUsedForSigning, _, _ := createJWKS(t)
keyNotUsedForSigning, _ := keySetNotUsedForSigning.Get(0)

//Override the kid of keyNotUsedForSigning to match the kid of keyUsedForSigning
require.NoError(t, keyNotUsedForSigning.Set(jwk.KeyIDKey, keyUsedForSigning.KeyID()))
JWTAuthJWKS.Override(ctx, &s.ClusterSettings().SV, serializePublicKeySet(t, keySetNotUsedForSigning))
JWTAuthIssuers.Override(ctx, &s.ClusterSettings().SV, validIssuer)

// Set audience field to audience2.
JWTAuthAudience.Override(ctx, &s.ClusterSettings().SV, audience2)

verifier := ConfigureJWTAuth(ctx, s.AmbientCtx(), s.ClusterSettings(), s.StorageClusterID())

// kid of keyUsedForSigning is found in the cluster setting, but the validation fails.
err = verifier.ValidateJWTLogin(ctx, s.ClusterSettings(), username.MakeSQLUsernameFromPreNormalizedString(username1), token, identMap)
require.ErrorContains(t, err, "JWT authentication: invalid token")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"issuer": "https://accounts.idp1.com",
"authorization_endpoint": "https://accounts.idp1.com/o/oauth2/v2/auth",
"device_authorization_endpoint": "https://oauth2.idp1apis.com/device/code",
"token_endpoint": "https://oauth2.idp1apis.com/token",
"userinfo_endpoint": "https://openidconnect.idp1apis.com/v1/userinfo",
"revocation_endpoint": "https://oauth2.idp1apis.com/revoke",
"jwks_uri": "https://www.idp1apis.com/oauth2/v3/certs",
"response_types_supported": [
"code",
"token",
"id_token",
"code token",
"code id_token",
"token id_token",
"code token id_token",
"none"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"email",
"profile"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic"
],
"claims_supported": [
"aud",
"email",
"email_verified",
"exp",
"family_name",
"given_name",
"iat",
"iss",
"locale",
"name",
"picture",
"sub"
],
"code_challenge_methods_supported": [
"plain",
"S256"
],
"grant_types_supported": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:device_code",
"urn:ietf:params:oauth:grant-type:jwt-bearer"
]
}
37 changes: 37 additions & 0 deletions pkg/ccl/jwtauthccl/testdata/www.idp1apis.com_oauth2_v3_certs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"keys": [
{
"e": "AQAB",
"kid": "9b0285c31bfd8b040e03157b19c4e960bdc10c6f",
"use": "sig",
"n": "uCYe4j3rIDaC9U8jCloiD5UP5cQCndcKr570LSxEznqNB0qpmtqDJBU-RuSJbMEYZ853AlezSWca8uqDBAgdIWPod-scaQTOTg049m9hFwQuP7FzXsAjtxiOHub0nrD60Dy7vI1dPoiyiFdox25JUdW6OSPyq2OlFxCPIQy4SpKvebXduA2ZeIY5TWE2wt0mVPo__s9NACn4Ni9GwsPCcgG6yn8oAJ-JW6xCLnz5_CycNlg178Sxj8LWVEisPbdEK9LhSwQ7V3YU7pfLpEAtGWHYrIcH3-Tfz6IkS9-UmAzbdjaGk2W-AXkZW8jiIbfNER7e4ZKLntC4Am4InHkJzw",
"alg": "RS256",
"kty": "RSA"
},
{
"e": "AQAB",
"alg": "RS256",
"n": "1yFBscIm7d2VYYx8dSK4R4b5EOLKoFXPdr-B9RVYaFS_XHso47Mdc5_oj8DwYGeeJgvJN6kKrDqRd3W3JmEkA-woKe6e0Vd56sMWvc2s94utfI8AiXBNwXAYnCQWGHnu9faF903JaRDJTeaRTSmbrSMibpshpK2PcOtOk0Fb9CyZm9E8jSMblMa3jhW8vlTnln3r4qgr1nwddbOj0WEmAjwA7G32EdlF5Oz30_HeTiEKpMtLumf0GbmCP23dyc8Ibrl8ahhEdGtBBb8tDCIroB2C_O_QBdYVE8GZW2ZUBSEx7-riMZ5h--2bweM94I6dMSBke9IZ2582Sn8j3lFEWw",
"kty": "RSA",
"use": "sig",
"kid": "456b52c81e36fead259231a6947e040e03ea1262"
},
{
"kty": "RSA",
"alg": "RS256",
"n": "sm72oBH-R2Rqt4hkjp66tz5qCtq42TMnVgZg2Pdm_zs7_-EoFyNs9sD1MKsZAFaBPXBHDiWywyaHhLgwETLN9hlJIZPzGCEtV3mXJFSYG-8L6t3kyKi9X1lUTZzbmNpE0tf-eMW-3gs3VQSBJQOcQnuiANxbSXwS3PFmi173C_5fDSuC1RoYGT6X3JqLc3DWUmBGucuQjPaUF0w6LMqEIy0W_WYbW7HImwANT6dT52T72md0JWZuAKsRRnRr_bvaUX8_e3K8Pb1K_t3dD6WSLvtmEfUnGQgLynVl3aV5sRYC0Hy_IkRgoxl2fd8AaZT1X_rdPexYpx152Pl_CHJ79Q",
"use": "sig",
"kid": "0ad1fec78504f447bae65bcf5afaedb65eec9e81",
"e": "AQAB"
},
{
"alg": "RS256",
"e": "AQAB",
"kid": "valid-kid-testing",
"kty": "RSA",
"n": "6x265Wl0SZLY6qYr7Vx6Zp8METTH9LMmHJ_hmRHU_kpnVJ_qxcWCcgwsJeGw37i5-rsUDVIhiRAhUcyUNW3DYxlTEvTTDAzSjSB94gSo4RoEAs8CIDA7tH_s9gKnVQ5KCkxgRYCIrckZpvDsLA7RcLcOcH4SHzxT0zMnybFz8p9hMbu04eB_Jpv1c6bhYYuAiwDnTKcBdgV7BdE-48mHx-IP5Tp3CDlhIlGmdmis31nm0SlOZtqzEPsT8M-0x_nOYCa63HSfzbP2YxKekPB5Sb_9yhNbRFgQq2Azo-v_6fxm93rqjZlfGiTUOTMTA1zM2veWDZL-5se2YRt8rQMtCQ",
"use": "sig"
}

]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"keys": [
{
"alg": "RS256",
"d": "hr2U_CBBKmDjuyXcCr1y0BjZ24p6BTwd3U2rBgP4InsVWKQE8a5NIXrkWhlLOgstWgmYZkHpQhliXvR1A2GSFdrPhw-TW1aF26cBPWQaPFaicdGckEHUFY8yh5Hhv5bey6QVj_8nVSDoeImdb2pWkNf3iHRXglsaVvD8HlR59FJVNt0A3KbSbiVe05HZuxxNer3b4_f9o2sLEuJxSojgY0qRUbJLdylbSp3rmAcScygcaLdK4sXdwyGzWp-hRGwxvSDuVp900JUU1rCfuuYFjL28bNbUelavvyDFhFN76yy-FEkWx01Ox2nt9eI3VwLs-KwgPf-U_1M5FL-QsW-W2Q",
"dp": "BLkTBppN71qxl8rxptU-CCK9nyZhRLJMJVmOu-8r3ZxBlXdcOJgz1xgH3ZNxYpL6-XA2Gvdctb_rGoo1dlBeupwbpBWVokYBsWLvKTdp5YyabvuoiEgA3rG_ZLdEERgQfoJdzqccOPCSuvZVkD0X7eSBwFjCHXH9yl0-kIqfOI0",
"dq": "8vWZuxsek1HhCnRv-WRvI7aD0St_fkeNV2JZpsR9XoDthpxWxjLOPaalUjfQQuhrZcgtcIH_9wUnOTeU17GPWiD-h-pkTHuloHrhAf9a8TWkYZwMIlQrVixo683MKNWkVAKKE4hEWt6l7JpJTjS1gvmjFNDtimdLqxy1alF7q-U",
"e": "AQAB",
"kid": "valid-kid-testing",
"kty": "RSA",
"n": "6x265Wl0SZLY6qYr7Vx6Zp8METTH9LMmHJ_hmRHU_kpnVJ_qxcWCcgwsJeGw37i5-rsUDVIhiRAhUcyUNW3DYxlTEvTTDAzSjSB94gSo4RoEAs8CIDA7tH_s9gKnVQ5KCkxgRYCIrckZpvDsLA7RcLcOcH4SHzxT0zMnybFz8p9hMbu04eB_Jpv1c6bhYYuAiwDnTKcBdgV7BdE-48mHx-IP5Tp3CDlhIlGmdmis31nm0SlOZtqzEPsT8M-0x_nOYCa63HSfzbP2YxKekPB5Sb_9yhNbRFgQq2Azo-v_6fxm93rqjZlfGiTUOTMTA1zM2veWDZL-5se2YRt8rQMtCQ",
"p": "9tUT8MGkEHXIKcFq7Waof4uWOstqYETD6KqvDdzYjhxqggexmTJPELaz-iSIyCNt6po95Ike2VckBfvq4B5tNuHWZLC7yTcc3WxPPVyAZpVukCV2zRKbs8Zy0zjpnglOgmvapSNKulgfwIYHDtUp2OSSV-Ma_Snl8Rq6i-Dr0yM",
"q": "89lAqtOqdusC2Psz-CUbB0Zq_yiIWIlbUdXFxv0jefmyKy4CKItF63XKexuWIEqzwVFMzhcJ5DdJpNYND2q8RroZrMeNvKVT0AvsktDbHETdnUinSecCbpqSzLEEiNkG7hg4mrIphb1W0fdp7PhSlHUq_GqtiKnkBGR17KjrB-M",
"qi": "ooUkn5a8TvSav3qLop4HpcxUWh5rF4tasrsWDTHBxsTv9kvgfQ7X3nsZJXABF7GieX9E9U-Lfi9ZcdMlIJe70z6eayRGkTvAbQO155ZiVGKRHkBi5k-WzvmrNBYrhXF8al2ABSk37IzjtPAQBBAfr8qAnf8xYbjar7yabqmpZ0M"
}
]
}
2 changes: 1 addition & 1 deletion pkg/ccl/testccl/authccl/testdata/jwt
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jwt_cluster_setting jwks={"keys":[{"kty":"RSA","use":"sig","alg":"RS256","kid":"
# see authentication_jwt_test.go for examples of how to generate these tokens.
connect user=jwt_user options=--crdb:jwt_auth_enabled=true password=eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3QyIn0.eyJhdWQiOiJ0ZXN0X2NsdXN0ZXIiLCJleHAiOjI2NjEyNjQyNjksImlhdCI6MTY2MTI2NDI2OSwiaXNzIjoiaXNzdWVyMiIsInN1YiI6InRlc3QyIn0.Tot41E-wSz24wo1wj3b8CwEr-O_dqWZoHZkAh2x4nfK2hT4yhfiOcajmKQJVVZX2_897c8uDOqfLzl77JEe-AX4mlEBZXWUNqwwQIdIFZxpL6FEV_YjvTF0bQuu9oeD7kYW-6i3-QQpB6QpCVb-wLW8bBbJ4zCap88nYk14HZH-ZYSzPAP7YEVppHQNhWrxQ66nQU__RuYeQdL6J5Edes9qCHUgqnZCnMPzDZ4l_3Pc5tTSNVcOUl5MMHsvrYsb0VtSFTNCOjJIADXbc2KzVbfqLt-ArUDxs36__u_g84TfGFXoT0VTDbDjYwD7wpyLuT3oLcJuA4m_tto6Rrn7Rww
----
ERROR: JWT authentication: invalid token (SQLSTATE 28000)
ERROR: JWT authentication: unable to validate token (SQLSTATE 28000)

jwt_cluster_setting jwks={"keys":[{"kty":"RSA","use":"sig","alg":"RS256","kid":"test","n":"sJCwOk5gVjZZu3oaODecZaT_-Lee7J-q3rQIvCilg-7B8fFNJ2XHZCsF74JX2d7ePyjz7u9d2r5CvstufiH0qGPHBBm0aKrxGRILRGUTfqBs8Dnrnv9ymTEFsRUQjgy9ACUfwcgLVQIwv1NozySLb4Z5N8X91b0TmcJun6yKjBrnr1ynUsI_XXjzLnDpJ2Ng_shuj-z7DKSEeiFUg9eSFuTeg_wuHtnnhw4Y9pwT47c-XBYnqtGYMADSVEzKLQbUini0p4-tfYboF6INluKQsO5b1AZaaXgmStPIqteS7r2eR3LFL-XB7rnZOR4cAla773Cq5DD-8RnYamnmmLu_gQ","e":"AQAB"},{"kty":"RSA","use":"sig","alg":"RS256","kid":"test2","n":"3gOrVdePypBAs6bTwD-6dZhMuwOSq8QllMihBfcsiRmo3c14_wfa_DRDy3kSsacwdih5-CaeF8ou-Dan6WqXzjDyJNekmGltPLfO2XB5FkHQoZ-X9lnXktsAgNLj3WsKjr-xUxrh8p8FFz62HJYN8QGaNttWBJZb3CgdzF7i8bPqVet4P1ekzs7mPBH2arEDy1f1q4o7fpmw0t9wuCrmtkj_g_eS6Hi2Rxm3m7HJUFVVbQeuZlT_W84FUzpSQCkNi2QDvoNVVCE2DSYZxDrzRxSZSv_fIh5XeJhwYY-f8iEfI4qx91ONGzGMvPn2GagrBnLBQRx-6RsORh4YmOOeeQ","e":"AQAB"}]}
----
Expand Down

0 comments on commit 9ceb3a2

Please sign in to comment.