diff --git a/internal/authz/oidc.go b/internal/authz/oidc.go index 51646919..3485f528 100644 --- a/internal/authz/oidc.go +++ b/internal/authz/oidc.go @@ -621,7 +621,7 @@ func (o *oidcHandler) isValidIDToken(ctx context.Context, log telemetry.Logger, return false, codes.Internal } - if _, err := jws.Verify([]byte(idTokenString), jws.WithKeySet(jwtSet)); err != nil { + if _, err := jws.Verify([]byte(idTokenString), jws.WithKeySet(jwtSet, jws.WithInferAlgorithmFromKey(true))); err != nil { log.Error("error verifying id token with fetched jwks", err) return false, codes.Internal } diff --git a/internal/authz/oidc_test.go b/internal/authz/oidc_test.go index 0331f3a7..84532490 100644 --- a/internal/authz/oidc_test.go +++ b/internal/authz/oidc_test.go @@ -194,7 +194,12 @@ func TestOIDCProcess(t *testing.T) { unknownJWKPriv, _ := newKeyPair(t) jwkPriv, jwkPub := newKeyPair(t) - bytes, err := json.Marshal(newKeySet(t, jwkPub)) + noAlgJwkPriv, noAlgJwkPub := newKeyPair(t) + noAlgJwkPriv.Set(jwk.KeyIDKey, noAlgKeyId) + noAlgJwkPub.Set(jwk.KeyIDKey, noAlgKeyId) + noAlgJwkPub.Remove(jwk.AlgorithmKey) + + bytes, err := json.Marshal(newKeySet(t, jwkPub, noAlgJwkPub)) require.NoError(t, err) basicOIDCConfig.JwksConfig = &oidcv1.OIDCConfig_Jwks{ Jwks: string(bytes), @@ -360,6 +365,23 @@ func TestOIDCProcess(t *testing.T) { requireStoredTokens(t, store, newSessionID, false) }, }, + { + name: "successfully retrieve new tokens when 'alg' is not specified in JWK", + req: callbackRequest, + storedAuthState: validAuthState, + mockTokensResponse: &idpTokensResponse{ + IDToken: newJWT(t, noAlgJwkPriv, jwt.NewBuilder().Audience([]string{"test-client-id"}).Claim("nonce", newNonce)), + AccessToken: "access-token", + TokenType: "Bearer", + }, + responseVerify: func(t *testing.T, resp *envoy.CheckResponse) { + require.Equal(t, int32(codes.Unauthenticated), resp.GetStatus().GetCode()) + requireStandardResponseHeaders(t, resp) + requireRedirectResponse(t, resp.GetDeniedResponse(), requestedAppURL, nil) + requireStoredTokens(t, store, sessionID, true) + requireStoredTokens(t, store, newSessionID, false) + }, + }, { name: "request is invalid, query parameters are missing", req: modifyCallbackRequestPath("/callback?"), @@ -1405,8 +1427,9 @@ func modifyCallbackRequestPath(path string) *envoy.CheckRequest { } const ( - keyID = "test" - keyAlg = jwa.RS256 + keyID = "test" + keyAlg = jwa.RS256 + noAlgKeyId = "noAlgTest" ) func newKeySet(t *testing.T, keys ...jwk.Key) jwk.Set {