fix(idtoken): allow WithCredentialsJSON to work with NewClient (#570)

Added new `internaloption.SkipDialSettingsValidation` that makes the call
to validate ClientOptions a no-op.
diff --git a/idtoken/idtoken.go b/idtoken/idtoken.go
index a5ee882..67c8965 100644
--- a/idtoken/idtoken.go
+++ b/idtoken/idtoken.go
@@ -16,6 +16,7 @@
 
 	"google.golang.org/api/internal"
 	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
 	htransport "google.golang.org/api/transport/http"
 )
 
@@ -50,7 +51,9 @@
 	if err != nil {
 		return nil, err
 	}
-	opts = append(opts, option.WithTokenSource(ts))
+	// Skip DialSettings validation so added TokenSource will not conflict with user
+	// provided credentials.
+	opts = append(opts, option.WithTokenSource(ts), internaloption.SkipDialSettingsValidation())
 	t, err := htransport.NewTransport(ctx, http.DefaultTransport, opts...)
 	if err != nil {
 		return nil, err
diff --git a/integration-tests/idtoken/idtoken_test.go b/integration-tests/idtoken/idtoken_test.go
index e2cc4e9..65f3169 100644
--- a/integration-tests/idtoken/idtoken_test.go
+++ b/integration-tests/idtoken/idtoken_test.go
@@ -14,6 +14,7 @@
 	"testing"
 
 	"golang.org/x/oauth2"
+	"golang.org/x/oauth2/google"
 	"google.golang.org/api/idtoken"
 	"google.golang.org/api/option"
 )
@@ -47,7 +48,7 @@
 	}
 }
 
-func TestNewClient(t *testing.T) {
+func TestNewClient_WithCredentialFile(t *testing.T) {
 	aud := os.Getenv(envTokenAudience)
 	client, err := idtoken.NewClient(context.Background(), aud, option.WithCredentialsFile(os.Getenv(envCredentialFile)))
 	if err != nil {
@@ -65,3 +66,27 @@
 		t.Fatalf("got %q, want %q", validTok.Audience, aud)
 	}
 }
+
+func TestNewClient_WithCredentialJSON(t *testing.T) {
+	aud := os.Getenv(envTokenAudience)
+	ctx := context.Background()
+	creds, err := google.FindDefaultCredentials(ctx)
+	if err != nil {
+		t.Fatalf("unable to find default creds: %v", err)
+	}
+	client, err := idtoken.NewClient(ctx, aud, option.WithCredentialsJSON(creds.JSON))
+	if err != nil {
+		t.Fatalf("unable to create Client: %v", err)
+	}
+	tok, err := client.Transport.(*oauth2.Transport).Source.Token()
+	if err != nil {
+		t.Fatalf("unable to retrieve Token: %v", err)
+	}
+	validTok, err := idtoken.Validate(context.Background(), tok.AccessToken, aud)
+	if err != nil {
+		t.Fatalf("token validation failed: %v", err)
+	}
+	if validTok.Audience != aud {
+		t.Fatalf("got %q, want %q", validTok.Audience, aud)
+	}
+}
diff --git a/internal/settings.go b/internal/settings.go
index f435519..3b779c2 100644
--- a/internal/settings.go
+++ b/internal/settings.go
@@ -38,6 +38,7 @@
 	TelemetryDisabled   bool
 	ClientCertSource    func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
 	CustomClaims        map[string]interface{}
+	SkipValidation      bool
 
 	// Google API system parameters. For more information please read:
 	// https://cloud.google.com/apis/docs/system-parameters
@@ -47,6 +48,9 @@
 
 // Validate reports an error if ds is invalid.
 func (ds *DialSettings) Validate() error {
+	if ds.SkipValidation {
+		return nil
+	}
 	hasCreds := ds.APIKey != "" || ds.TokenSource != nil || ds.CredentialsFile != "" || ds.Credentials != nil
 	if ds.NoAuth && hasCreds {
 		return errors.New("options.WithoutAuthentication is incompatible with any option that provides credentials")
diff --git a/option/internaloption/internaloption.go b/option/internaloption/internaloption.go
index ff5b530..d5debb7 100644
--- a/option/internaloption/internaloption.go
+++ b/option/internaloption/internaloption.go
@@ -34,7 +34,19 @@
 // WithDefaultMTLSEndpoint is an option that indicates the default mTLS endpoint.
 //
 // It should only be used internally by generated clients.
-//
 func WithDefaultMTLSEndpoint(url string) option.ClientOption {
 	return defaultMTLSEndpointOption(url)
 }
+
+// SkipDialSettingsValidation bypasses validation on ClientOptions.
+//
+// It should only be used internally.
+func SkipDialSettingsValidation() option.ClientOption {
+	return skipDialSettingsValidation{}
+}
+
+type skipDialSettingsValidation struct{}
+
+func (s skipDialSettingsValidation) Apply(settings *internal.DialSettings) {
+	settings.SkipValidation = true
+}