go-oci8: External/kerberos authentication not working
We’re attempting to use kerberos authentication to connect to an Oracle 12.x database, using go-oci8
commit id 96a3284b269c
. We can connect to the database using go-oci8 with username+password
, and we can connect using sqlplus+kerberos
, but when we try to use go-oci8+kerberos
, it fails with:
Failed to connect to DB: ORA-01017: invalid username/password; logon denied
This problem persists whether we use a connect string directly or a host defined in our tnsnames.ora
.
After some digging, we were able to successfully connect by messing around with dsn.externalauthentication
. By reversing the test at https://github.com/mattn/go-oci8/blob/master/oci8.go#L323 such that it does not execute that block when dsn.externalauthentication
is set to false
, the connection works and we’re able to proceed normally.
Now to the meat of our question: what is the purpose of dsn.externalauthentication
? Based on the name, we presume it’s when the library itself isn’t handling authentication via username and password. However, it appears to be somewhat overloaded, as setting it to true requires not just the username and password fields to be empty, but also the dsn.Connect
field (https://github.com/mattn/go-oci8/blob/master/oci8.go#L125). And to reinforce that having an empty hostname is required for external auth, down at line https://github.com/mattn/go-oci8/blob/master/oci8.go#L279 there is another test for dsn.externalauthentication
where, if it’s true, the database server to use is set to nil
.
If dsn.externalauthentication
is to be used for our use-case (kerberos authentication), how do we pass in the name of the server to connect to? And if it’s not for our use case, then how to we configure our connection string to work?
Finally, we’re happy to provide a pull request that converts “external authentication” to only requiring username and password to be empty, without also requiring the hostname to be empty, if that sounds reasonable. We’re also happy to hear what we’re doing wrong as we’re not actually well versed in kerberos authentication (this being our first attempt at using it), and if we’re missing something obvious, that doesn’t require patching go-oci8
, that’s even better.
Thanks for your time and I’ll be glad to answer any follow-up questions you have.
David
Example code that we’re using to test our connection:
package main
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-oci8"
)
func main() {
// WORKS
db, err := sql.Open("oci8", "username/password@TEST")
// DOESN'T WORK
// db, err := sql.Open("oci8", "/@TEST")
// NOR DOES
// db, err := sql.Open("oci8", "@TEST")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
if err = db.Ping(); err != nil {
fmt.Printf("Error connecting to the database: %s\n", err)
return
} else {
fmt.Printf("Connected successfully\n")
}
}
where TEST
is defined as a server in our tnsnames.ora
:
TEST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = test.foo.us-west-1.rds.amazonaws.com)(PORT = 1521))
(CONNECT_DATA =
(SID = ORCL)
)
)
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 15 (8 by maintainers)
It works in our test environment, but we want to test it against the real thing, which we hopefully should be able to do tomorrow. I will absolutely update/close this at that point. Thank you!