与SQL Server的Kerberos连接是否需要在连接属性中提供密码?

时间:2019-07-11 09:52:03

标签: sql-server kerberos

我正在尝试使用keytab连接到sql server,并且抛出以下错误

  

com.microsoft.sqlserver.jdbc.SQLServerException:无法使用Kerberos主体DOMAIN \ User登录,请检查您的凭据。 Kerberos登录失败:集成身份验证失败。由于javax.security.auth.login.LoginException而导致ClientConnectionId:6f436f49-b0bf-441e-bab3-e6af86ac8361(无法获得任何属性:con属性中的[password,PASSWORD]无法从用户那里获取身份验证信息)           在com.microsoft.sqlserver.jdbc.KerbAuthentication.intAuthInit(KerbAuthentication.java:108)           在com.microsoft.sqlserver.jdbc.KerbAuthentication.GenerateClientContext(KerbAuthentication.java:399)           在com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:4049)           在com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:3157)           在com.microsoft.sqlserver.jdbc.SQLServerConnection.access $ 100(SQLServerConnection.java:82)           在com.microsoft.sqlserver.jdbc.SQLServerConnection $ LogonCommand.doExecute(SQLServerConnection.java:3121)           在com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7151)           在com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2478)           在com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2026)           在com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:1687)           在com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:1528)           在com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:866)           在com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:569)           在java.sql.DriverManager.getConnection(未知来源)           在java.sql.DriverManager.getConnection(未知来源)           在com.adventnet.appmanager.server.mssql.datacollection.MSSQLKerberosAuthenticationTest.main(MSSQLKerberosAuthenticationTest.java:47)   由以下原因引起:javax.security.auth.login.LoginException:无法获取任何属性:con属性中的[password,PASSWORD]无法从用户那里获取身份验证信息           在com.sun.security.auth.module.Krb5LoginModule.promptForPass(未知来源)           在com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(未知来源)           在com.sun.security.auth.module.Krb5LoginModule.login(未知来源)           在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处           在sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)           在sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)           在java.lang.reflect.Method.invoke(未知来源)           在javax.security.auth.login.LoginContext.invoke(未知来源)           在javax.security.auth.login.LoginContext.access $ 000(未知源)           在javax.security.auth.login.LoginContext $ 4.run(未知源)           在javax.security.auth.login.LoginContext $ 4.run(未知源)           在java.security.AccessController.doPrivileged(本机方法)           在javax.security.auth.login.LoginContext.invokePriv中(未知源)           在javax.security.auth.login.LoginContext.login处(未知来源)           在com.microsoft.sqlserver.jdbc.KerbAuthentication.intAuthInit(KerbAuthentication.java:87)           ...另外15个

当我尝试使用密码时,它已成功连接。

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);

对于kerberos连接,连接属性中的密码是否是必需的?单靠Keytab还不够吗?

1 个答案:

答案 0 :(得分:1)

首先需要对域进行身份验证。例如在使用MIT Kerberos的Linux和MacOS上,您可以使用kinit命令来获取kerberos票证。

获得许可后,您就可以通过该票证对Sql进行身份验证,而无需提供其他任何东西。

[更新]

如果您的主机和目标都在Windows域中,并且它们都在同一个域中,那么您应该已经可以使用了。

也就是说,Sql将仅允许 使用Kerberos 进行身份验证,前提是运行引擎的服务帐户有权创建Service Principal Name(或具有适当权限的用户已使用setSPN命令创建了 SPN

通过查看Sql Error Log中的类似文本,您可以判断Sql是否能够注册 SPN

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

除了 StackOverflow 答案中所涵盖的内容外,Kerberos还有很多内容。