1
votes

I am trying to connect to sql server by using keytab and it throws below error

com.microsoft.sqlserver.jdbc.SQLServerException: Cannot login with Kerberos principal DOMAIN\User, check your credentials. Kerberos Login failed: Integrated authentication failed. ClientConnectionId:6f436f49-b0bf-441e-bab3-e6af86ac8361 due to javax.security.auth.login.LoginException (Cannot get any of properties: [password, PASSWORD] from con properties not available to garner authentication information from the user) at com.microsoft.sqlserver.jdbc.KerbAuthentication.intAuthInit(KerbAuthentication.java:108) at com.microsoft.sqlserver.jdbc.KerbAuthentication.GenerateClientContext(KerbAuthentication.java:399) at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:4049) at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:3157) at com.microsoft.sqlserver.jdbc.SQLServerConnection.access$100(SQLServerConnection.java:82) at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:3121) at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7151) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2478) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2026) at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:1687) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:1528) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:866) at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:569) at java.sql.DriverManager.getConnection(Unknown Source) at java.sql.DriverManager.getConnection(Unknown Source) at com.adventnet.appmanager.server.mssql.datacollection.MSSQLKerberosAuthenticationTest.main(MSSQLKerberosAuthenticationTest.java:47) Caused by: javax.security.auth.login.LoginException: Cannot get any of properties: [password, PASSWORD] from con properties not available to garner authentication information from the user at com.sun.security.auth.module.Krb5LoginModule.promptForPass(Unknown Source) at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Unknown Source) at com.sun.security.auth.module.Krb5LoginModule.login(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at javax.security.auth.login.LoginContext.invoke(Unknown Source) at javax.security.auth.login.LoginContext.access$000(Unknown Source) at javax.security.auth.login.LoginContext$4.run(Unknown Source) at javax.security.auth.login.LoginContext$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.login.LoginContext.invokePriv(Unknown Source) at javax.security.auth.login.LoginContext.login(Unknown Source) at com.microsoft.sqlserver.jdbc.KerbAuthentication.intAuthInit(KerbAuthentication.java:87) ... 15 more

When I try with password it is connected successfully.

String home = System.getProperty("user.dir");
String  filePath = home + File.separator + "conf" + File.separator + "KerberosConfigurations" + File.separator + "MSSQL";// NO I18N
System.setProperty("java.security.krb5.debug", "true");
System.setProperty("java.security.auth.login.config", filePath+File.separator+"login.conf");
System.setProperty("java.security.krb5.conf", filePath+File.separator+"krb5.ini");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
String connectionUrl = "jdbc:sqlserver://"+hostName+":"+port+";databaseName=master;sendStringParametersAsUnicode=true;applicationName=test;"; //NO I18N
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Properties dbConProp = new Properties();
dbConProp.put("integratedSecurity", "true");
dbConProp.put("authenticationScheme", "JavaKerberos");
dbConProp.put("instanceName",instanceName);
dbConProp.put("user",user);
//dbConProp.put("password",pwd);
con = DriverManager.getConnection(connectionUrl,dbConProp);

Does password in connection properties is mandatory for kerberos connection? Keytab alone not sufficient ?

1
If you are using Kerboros, you don't supply the Username or Password; the connection uses the credentials of the already authenticated Windows Account the application is running as.Larnu

1 Answers

2
votes

The client needs to be authenticated to the domain first. e.g. on Linux and MacOS using MIT Kerberos, you can use the kinit command to get a kerberos ticket.

Once granted you can then authenticate to Sql via that ticket without supplying anything else.

[Update]

If your host and target are both on a Windows domain and they're on the same domain, then you should already be good to go.

That said, Sql will only allow you to authenticate using Kerberos if the service account that is running the engine has privileges to create a Service Principal Name (or a user with appropriate rights has created a SPN with the setSPN command).

You can tell if Sql's been able to register the SPN by looking at the Sql Error Log for text like

The SQL Server Network Interface library successfully registered the Service Principal Name (SPN) [ MSSQLSvc/MySqlServerHostName:1433 ] for the SQL Server service

There's a lot to Kerberos than can be covered in just a StackOverflow Answer.