diff --git a/conn.go b/conn.go index 3daca6250..ae02bd71c 100644 --- a/conn.go +++ b/conn.go @@ -43,25 +43,11 @@ import ( "github.com/gocql/gocql/internal/streams" ) -var ( - defaultApprovedAuthenticators = []string{ - "org.apache.cassandra.auth.PasswordAuthenticator", - "com.instaclustr.cassandra.auth.SharedSecretAuthenticator", - "com.datastax.bdp.cassandra.auth.DseAuthenticator", - "io.aiven.cassandra.auth.AivenAuthenticator", - "com.ericsson.bss.cassandra.ecaudit.auth.AuditPasswordAuthenticator", - "com.amazon.helenus.auth.HelenusAuthenticator", - "com.ericsson.bss.cassandra.ecaudit.auth.AuditAuthenticator", - "com.scylladb.auth.SaslauthdAuthenticator", - "com.scylladb.auth.TransitionalAuthenticator", - "com.instaclustr.cassandra.auth.InstaclustrPasswordAuthenticator", - } -) - -// approve the authenticator with the list of allowed authenticators or default list if approvedAuthenticators is empty. +// approve the authenticator with the list of allowed authenticators. If the provided list is empty, +// the given authenticator is allowed. func approve(authenticator string, approvedAuthenticators []string) bool { if len(approvedAuthenticators) == 0 { - approvedAuthenticators = defaultApprovedAuthenticators + return true } for _, s := range approvedAuthenticators { if authenticator == s { @@ -86,9 +72,15 @@ type Authenticator interface { Success(data []byte) error } +// PasswordAuthenticator specifies credentials to be used when authenticating. +// It can be configured with an "allow list" of authenticator class names to avoid +// attempting to authenticate with Cassandra if it doesn't provide an expected authenticator. type PasswordAuthenticator struct { - Username string - Password string + Username string + Password string + // Setting this to nil or empty will allow authenticating with any authenticator + // provided by the server. This is the default behavior of most other driver + // implementations. AllowedAuthenticators []string } diff --git a/conn_test.go b/conn_test.go index cab4c2f8f..6cf062d95 100644 --- a/conn_test.go +++ b/conn_test.go @@ -55,18 +55,21 @@ const ( func TestApprove(t *testing.T) { tests := map[bool]bool{ - approve("org.apache.cassandra.auth.PasswordAuthenticator", []string{}): true, - approve("com.instaclustr.cassandra.auth.SharedSecretAuthenticator", []string{}): true, - approve("com.datastax.bdp.cassandra.auth.DseAuthenticator", []string{}): true, - approve("io.aiven.cassandra.auth.AivenAuthenticator", []string{}): true, - approve("com.amazon.helenus.auth.HelenusAuthenticator", []string{}): true, - approve("com.ericsson.bss.cassandra.ecaudit.auth.AuditAuthenticator", []string{}): true, - approve("com.scylladb.auth.SaslauthdAuthenticator", []string{}): true, - approve("com.scylladb.auth.TransitionalAuthenticator", []string{}): true, - approve("com.instaclustr.cassandra.auth.InstaclustrPasswordAuthenticator", []string{}): true, - approve("com.apache.cassandra.auth.FakeAuthenticator", []string{}): false, - approve("com.apache.cassandra.auth.FakeAuthenticator", nil): false, - approve("com.apache.cassandra.auth.FakeAuthenticator", []string{"com.apache.cassandra.auth.FakeAuthenticator"}): true, + approve("org.apache.cassandra.auth.PasswordAuthenticator", []string{}): true, + approve("org.apache.cassandra.auth.MutualTlsWithPasswordFallbackAuthenticator", []string{}): true, + approve("org.apache.cassandra.auth.MutualTlsAuthenticator", []string{}): true, + approve("com.instaclustr.cassandra.auth.SharedSecretAuthenticator", []string{}): true, + approve("com.datastax.bdp.cassandra.auth.DseAuthenticator", []string{}): true, + approve("io.aiven.cassandra.auth.AivenAuthenticator", []string{}): true, + approve("com.amazon.helenus.auth.HelenusAuthenticator", []string{}): true, + approve("com.ericsson.bss.cassandra.ecaudit.auth.AuditAuthenticator", []string{}): true, + approve("com.scylladb.auth.SaslauthdAuthenticator", []string{}): true, + approve("com.scylladb.auth.TransitionalAuthenticator", []string{}): true, + approve("com.instaclustr.cassandra.auth.InstaclustrPasswordAuthenticator", []string{}): true, + approve("com.apache.cassandra.auth.FakeAuthenticator", []string{}): true, + approve("com.apache.cassandra.auth.FakeAuthenticator", nil): true, + approve("com.apache.cassandra.auth.FakeAuthenticator", []string{"com.apache.cassandra.auth.FakeAuthenticator"}): true, + approve("com.apache.cassandra.auth.FakeAuthenticator", []string{"com.apache.cassandra.auth.NotFakeAuthenticator"}): false, } for k, v := range tests { if k != v { diff --git a/doc.go b/doc.go index f23e812c5..236b55e2f 100644 --- a/doc.go +++ b/doc.go @@ -81,6 +81,16 @@ // } // defer session.Close() // +// By default, PasswordAuthenticator will attempt to authenticate regardless of what implementation the server returns +// in its AUTHENTICATE message as its authenticator, (e.g. org.apache.cassandra.auth.PasswordAuthenticator). If you +// wish to restrict this you may use PasswordAuthenticator.AllowedAuthenticators: +// +// cluster.Authenticator = gocql.PasswordAuthenticator { +// Username: "user", +// Password: "password" +// AllowedAuthenticators: []string{"org.apache.cassandra.auth.PasswordAuthenticator"}, +// } +// // # Transport layer security // // It is possible to secure traffic between the client and server with TLS.