From 017b0f1eac837d57c8c33b582b29518cc6e2ac09 Mon Sep 17 00:00:00 2001 From: edanidzerda <19670937+edanidzerda@users.noreply.github.com> Date: Tue, 13 Jun 2023 10:33:49 -0400 Subject: [PATCH 1/3] Added a new connection property "useDefaultJaasConfig" * New option to allow the JDBC driver to perform Kerberos authentication using its builtin JaasConfiguration(), to easily coexist with an external JAAS configuration that does not provide a SQLJDBCDriver Login module configuration. * Warning is printed if the jaasConfigurationName is non-default at the same time as useDefaultJaasConfig, as the jaasConfigurationName will not be used. --- .../sqlserver/jdbc/ISQLServerDataSource.java | 25 +++++++++++++++---- .../sqlserver/jdbc/KerbAuthentication.java | 20 ++++++++++++++- .../sqlserver/jdbc/SQLServerDataSource.java | 12 +++++++++ .../sqlserver/jdbc/SQLServerDriver.java | 6 ++++- .../sqlserver/jdbc/SQLServerResource.java | 3 ++- .../jdbc/SQLServerConnectionTest.java | 3 +++ 6 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataSource.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataSource.java index a435666e1..019b79997 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataSource.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataSource.java @@ -802,7 +802,7 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource { int getSocketTimeout(); /** - * Sets the login configuration file for Kerberos authentication. This overrides the default configuration + * Sets the login configuration name for Kerberos authentication. This overrides the default configuration * SQLJDBCDriver * * @param configurationName @@ -814,7 +814,7 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource { void setJASSConfigurationName(String configurationName); /** - * Returns the login configuration file for Kerberos authentication. + * Returns the login configuration name for Kerberos authentication. * * * @return login configuration file name @@ -825,7 +825,7 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource { String getJASSConfigurationName(); /** - * Sets the login configuration file for Kerberos authentication. This overrides the default configuration + * Sets the login configuration name for Kerberos authentication. This overrides the default configuration * SQLJDBCDriver * * @@ -835,12 +835,27 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource { void setJAASConfigurationName(String configurationName); /** - * Returns the login configuration file for Kerberos authentication. + * Returns the login configuration name for Kerberos authentication. * - * @return login configuration file name + * @return login configuration name */ String getJAASConfigurationName(); + /** + * Returns whether the default JAAS Configuration should be used + * + * @return useDefaultJaasConfig boolean value + */ + boolean getUseDefaultJaasConfig(); + + /** + * Sets whether the default JAAS Configuration will be used. This means the system-wide JAAS configuration + * is ignored to avoid conflicts with libraries that override the JAAS configuration. + * + * @param useDefaultJaasConfig + * boolean property to use the default JAAS configuration + */ + void setUseDefaultJaasConfig(boolean useDefaultJaasConfig); /** * Sets whether Fips Mode should be enabled/disabled on the connection. For FIPS enabled JVM this property should be * true. diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java index ffc016448..b58bb9fae 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java @@ -73,13 +73,31 @@ private void initAuthInit() throws SQLServerException { String configName = con.activeConnectionProperties.getProperty( SQLServerDriverStringProperty.JAAS_CONFIG_NAME.toString(), SQLServerDriverStringProperty.JAAS_CONFIG_NAME.getDefaultValue()); + boolean useDefaultJaas = Boolean.parseBoolean(con.activeConnectionProperties.getProperty( + SQLServerDriverBooleanProperty.USE_DEFAULT_JAAS_CONFIG.toString(), + Boolean.toString(SQLServerDriverBooleanProperty.USE_DEFAULT_JAAS_CONFIG.getDefaultValue()))); + + if (!configName.equals( + SQLServerDriverStringProperty.JAAS_CONFIG_NAME.getDefaultValue()) && useDefaultJaas) { + // Reset configName to default -- useDefaultJaas setting takes priority over jaasConfigName + if (authLogger.isLoggable(Level.WARNING)) { + authLogger.warning(toString() + String.format( + "Using default JAAS configuration, configured %s=%s will not be used.", + SQLServerDriverStringProperty.JAAS_CONFIG_NAME, configName)); + } + configName = SQLServerDriverStringProperty.JAAS_CONFIG_NAME.getDefaultValue(); + } Subject currentSubject; KerbCallback callback = new KerbCallback(con); try { AccessControlContext context = AccessController.getContext(); currentSubject = Subject.getSubject(context); if (null == currentSubject) { - lc = new LoginContext(configName, callback); + if (useDefaultJaas) { + lc = new LoginContext(configName, null, callback, new JaasConfiguration(null)); + } else { + lc = new LoginContext(configName, callback); + } lc.login(); // per documentation LoginContext will instantiate a new subject. currentSubject = lc.getSubject(); diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java index b7e018112..216ef569a 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java @@ -1030,6 +1030,18 @@ public String getJAASConfigurationName() { SQLServerDriverStringProperty.JAAS_CONFIG_NAME.getDefaultValue()); } + @Override + public boolean getUseDefaultJaasConfig() { + return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_DEFAULT_JAAS_CONFIG.toString(), + SQLServerDriverBooleanProperty.USE_DEFAULT_JAAS_CONFIG.getDefaultValue()); + } + + @Override + public void setUseDefaultJaasConfig(boolean useDefaultJaasConfig) { + setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_DEFAULT_JAAS_CONFIG.toString(), + useDefaultJaasConfig); + } + /** * @deprecated This method is deprecated. Use {@link SQLServerDataSource#setUser(String user)} instead. * diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java index 1bd92024c..966ffb079 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java @@ -693,7 +693,8 @@ enum SQLServerDriverBooleanProperty { USE_BULK_COPY_FOR_BATCH_INSERT("useBulkCopyForBatchInsert", false), USE_FMT_ONLY("useFmtOnly", false), SEND_TEMPORAL_DATATYPES_AS_STRING_FOR_BULK_COPY("sendTemporalDataTypesAsStringForBulkCopy", true), - DELAY_LOADING_LOBS("delayLoadingLobs", true); + DELAY_LOADING_LOBS("delayLoadingLobs", true), + USE_DEFAULT_JAAS_CONFIG("useDefaultJaasConfig", false); private final String name; private final boolean defaultValue; @@ -892,6 +893,9 @@ public final class SQLServerDriver implements java.sql.Driver { null), new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.JAAS_CONFIG_NAME.toString(), SQLServerDriverStringProperty.JAAS_CONFIG_NAME.getDefaultValue(), false, null), + new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.USE_DEFAULT_JAAS_CONFIG.toString(), + Boolean.toString(SQLServerDriverBooleanProperty.USE_DEFAULT_JAAS_CONFIG.getDefaultValue()), false, + TRUE_FALSE), new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.SSL_PROTOCOL.toString(), SQLServerDriverStringProperty.SSL_PROTOCOL.getDefaultValue(), false, new String[] {SSLProtocol.TLS.toString(), SSLProtocol.TLS_V10.toString(), diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java index a9047e6bc..0652a4205 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java @@ -449,7 +449,8 @@ protected Object[][] getContents() { {"R_kerberosLoginFailedForUsername", "Cannot login with Kerberos principal {0}, check your credentials. {1}"}, {"R_kerberosLoginFailed", "Kerberos Login failed: {0} due to {1} ({2})"}, {"R_StoredProcedureNotFound", "Could not find stored procedure ''{0}''."}, - {"R_jaasConfigurationNamePropertyDescription", "Login configuration file for Kerberos authentication."}, + {"R_jaasConfigurationNamePropertyDescription", "Login configuration name for Kerberos authentication."}, + {"R_useDefaultJaasConfigPropertyDescription", "Use the default JAAS configuration for Kerberos authentication."}, {"R_AKVKeyNotFound", "Key not found: {0}"}, {"R_SQLVariantSupport", "SQL_VARIANT is not supported in versions of SQL Server before 2008."}, {"R_invalidProbbytes", "SQL_VARIANT: invalid probBytes for {0} type."}, diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java index 52b1413c3..70336f8d3 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/SQLServerConnectionTest.java @@ -138,6 +138,9 @@ public void testDataSource() throws SQLServerException { ds.setJAASConfigurationName(stringPropValue); assertEquals(stringPropValue, ds.getJAASConfigurationName(), TestResource.getResource("R_valuesAreDifferent")); + ds.setUseDefaultJaasConfig(booleanPropValue); + assertEquals(booleanPropValue, ds.getUseDefaultJaasConfig(), TestResource.getResource("R_valuesAreDifferent")); + ds.setMSIClientId(stringPropValue); assertEquals(stringPropValue, ds.getMSIClientId(), TestResource.getResource("R_valuesAreDifferent")); From 39ec87bd6caa2ff8f3ff075d0198917db4d2db35 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Tue, 26 Sep 2023 21:25:14 -0700 Subject: [PATCH 2/3] Added tests for useDefaultJaasConfig --- pom.xml | 9 +- ...pySendTemporalDataTypesAsStringAETest.java | 1 + .../CallableStatementTest.java | 1 + .../JDBCEncryptionDecryptionTest.java | 1 + .../AlwaysEncrypted/MultiUserAKVTest.java | 1 + .../ParameterMetaDataCacheTest.java | 1 + .../AlwaysEncrypted/PrecisionScaleTest.java | 1 + .../RegressionAlwaysEncryptedTest.java | 1 + .../sqlserver/jdbc/KerberosTest.java | 105 ++++++++++++++++++ .../sqlserver/jdbc/TestResource.java | 1 + .../sqlserver/testframework/AbstractTest.java | 18 ++- .../sqlserver/testframework/Constants.java | 2 + 12 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/KerberosTest.java diff --git a/pom.xml b/pom.xml index b1b6e0afe..a2c21f35f 100644 --- a/pom.xml +++ b/pom.xml @@ -37,17 +37,18 @@ xSQLv11 - - - - - - For tests not compatible with SQL Server 2012 - - - - xSQLv12 - - - - - - For tests not compatible with SQL Server 2008 R2 - 2014 xSQLv14 - - - - - - For tests not compatible with SQL Server 2016 - 2017 - xSQLv15 - - - - - - For tests not compatible with SQL Server 2019 - - - - + xSQLv15 - - - - - - For tests not compatible with SQL Server 2019 - - - - xAzureSQLDB - - - - For tests not compatible with Azure SQL Database - - xAzureSQLDW - - - - For tests not compatible with Azure Data Warehouse - xAzureSQLMI - - - - For tests not compatible with Azure SQL Managed Instance - NTLM - - - - - - For tests using NTLM Authentication mode (excluded by default) - reqExternalSetup - For tests requiring external setup (excluded by default) + NTLM - - - - - - - For tests using NTLM Authentication mode (excluded by default) + Kerberos - - - - - For tests using Kerberos authentication (excluded by default) + reqExternalSetup - For tests requiring external setup (excluded by default) clientCertAuth - - For tests requiring client certificate authentication setup (excluded by default) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default testing enabled with SQL Server 2019 (SQLv15) --> - xSQLv12,xSQLv15,NTLM,MSI,reqExternalSetup,clientCertAuth,fedAuth + xSQLv12,xSQLv15,NTLM,MSI,reqExternalSetup,clientCertAuth,fedAuth,Kerberos -preview diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java index d8552ad3d..6dd177ab5 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/BulkCopySendTemporalDataTypesAsStringAETest.java @@ -57,6 +57,7 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDB) @Tag(Constants.xAzureSQLDW) +@Tag(Constants.reqExternalSetup) public class BulkCopySendTemporalDataTypesAsStringAETest extends AESetup { static String inputFile = "BulkCopyCSVSendTemporalDataTypesAsStringForBulkCopy.csv"; static String encoding = "UTF-8"; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java index 58ed2e63a..95531d698 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/CallableStatementTest.java @@ -53,6 +53,7 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) public class CallableStatementTest extends AESetup { private static String multiStatementsProcedure = AbstractSQLGenerator diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java index d4c2771c5..7376baca7 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/JDBCEncryptionDecryptionTest.java @@ -64,6 +64,7 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) public class JDBCEncryptionDecryptionTest extends AESetup { private boolean nullable = false; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java index 257d8f921..77630e8a4 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/MultiUserAKVTest.java @@ -58,6 +58,7 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) public class MultiUserAKVTest extends AESetup { private static Map requiredKeyStoreProvider = new HashMap<>(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/ParameterMetaDataCacheTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/ParameterMetaDataCacheTest.java index 5f84e7cbb..cef219d4a 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/ParameterMetaDataCacheTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/ParameterMetaDataCacheTest.java @@ -32,6 +32,7 @@ @Tag(Constants.xSQLv11) @Tag(Constants.xSQLv12) @Tag(Constants.xSQLv14) +@Tag(Constants.reqExternalSetup) public class ParameterMetaDataCacheTest extends AESetup { @BeforeAll diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java index 5343b1fcd..162fe8cef 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/PrecisionScaleTest.java @@ -42,6 +42,7 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) public class PrecisionScaleTest extends AESetup { private static java.util.Date date = null; private static int offsetFromGMT = 0; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java index 87584eb79..82ec693e0 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/RegressionAlwaysEncryptedTest.java @@ -29,6 +29,7 @@ @Tag(Constants.xSQLv12) @Tag(Constants.xAzureSQLDW) @Tag(Constants.xAzureSQLDB) +@Tag(Constants.reqExternalSetup) public class RegressionAlwaysEncryptedTest extends AESetup { static String numericTable[][] = {{"Bit", "bit"}, {"Tinyint", "tinyint"}, {"Smallint", "smallint"},}; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/KerberosTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/KerberosTest.java new file mode 100644 index 000000000..8755f468d --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/KerberosTest.java @@ -0,0 +1,105 @@ +package com.microsoft.sqlserver.jdbc; + +import com.microsoft.sqlserver.testframework.AbstractTest; +import com.microsoft.sqlserver.testframework.Constants; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.Configuration; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.util.HashMap; +import java.util.Map; + +@RunWith(JUnitPlatform.class) +public class KerberosTest extends AbstractTest { + + private static String kerberosAuth = "KERBEROS"; + + @BeforeAll + public static void setupTests() throws Exception { + setConnection(); + } + + @Tag(Constants.Kerberos) + @Test + public void testUseDefaultJaasConfigConnectionStringPropertyTrue() throws Exception { + String connectionStringUseDefaultJaasConfig = connectionStringKerberos + ";useDefaultJaasConfig=true;"; + + // Initial connection should succeed with default JAAS config + try (SQLServerConnection conn = (SQLServerConnection) DriverManager.getConnection(connectionStringUseDefaultJaasConfig)) { + ResultSet rs = conn.createStatement().executeQuery("select auth_scheme from sys.dm_exec_connections where session_id=@@spid"); + rs.next(); + Assertions.assertEquals(kerberosAuth, rs.getString(1)); + } + + // Attempt to overwrite JAAS config. Since useDefaultJaasConfig=true, this should have no effect + // and subsequent connections should succeed. + overwriteJaasConfig(); + + // New connection should successfully connect and continue to use the default JAAS config. + try (SQLServerConnection conn = (SQLServerConnection) DriverManager.getConnection(connectionStringUseDefaultJaasConfig)) { + ResultSet rs = conn.createStatement().executeQuery("select auth_scheme from sys.dm_exec_connections where session_id=@@spid"); + rs.next(); + Assertions.assertEquals(kerberosAuth, rs.getString(1)); + } + } + + @Tag(Constants.Kerberos) + @Test + public void testUseDefaultJaasConfigConnectionStringPropertyFalse() throws Exception { + + // useDefaultJaasConfig=false by default + // Initial connection should succeed with default JAAS config + try (SQLServerConnection conn = (SQLServerConnection) DriverManager.getConnection(connectionStringKerberos)) { + ResultSet rs = conn.createStatement().executeQuery("select auth_scheme from sys.dm_exec_connections where session_id=@@spid"); + rs.next(); + Assertions.assertEquals(kerberosAuth, rs.getString(1)); + } + + // Overwrite JAAS config. Since useDefaultJaasConfig=false, overwriting should succeed and have an effect. + // Subsequent connections will fail. + overwriteJaasConfig(); + + // New connection should fail as it is attempting to connect using an overwritten JAAS config. + try (SQLServerConnection conn = (SQLServerConnection) DriverManager.getConnection(connectionStringKerberos)) { + Assertions.fail(TestResource.getResource("R_expectedExceptionNotThrown")); + } catch (SQLServerException e) { + Assertions.assertTrue(e.getMessage() + .contains(TestResource.getResource("R_noLoginModulesConfiguredForJdbcDriver"))); + } + } + + /** + * Overwrites the default JAAS config. Call before making a connection. + */ + private static void overwriteJaasConfig() { + AppConfigurationEntry kafkaClientConfigurationEntry = new AppConfigurationEntry( + "com.sun.security.auth.module.Krb5LoginModule", + AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, + new HashMap<>()); + Map configurationEntries = new HashMap<>(); + configurationEntries.put("KAFKA_CLIENT_CONTEXT_NAME", + new AppConfigurationEntry[] { kafkaClientConfigurationEntry }); + Configuration.setConfiguration(new InternalConfiguration(configurationEntries)); + } + + private static class InternalConfiguration extends Configuration { + private final Map configurationEntries; + + InternalConfiguration(Map configurationEntries) { + this.configurationEntries = configurationEntries; + } + + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(String name) { + return this.configurationEntries.get(name); + } + + } +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java b/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java index 1df539411..c21f56101 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java @@ -203,5 +203,6 @@ protected Object[][] getContents() { {"R_connectTimedOut", "connect timed out"}, {"R_sessionKilled", "Cannot continue the execution because the session is in the kill state"}, {"R_failedFedauth", "Failed to acquire fedauth token: "}, + {"R_noLoginModulesConfiguredForJdbcDriver", "javax.security.auth.login.LoginException (No LoginModules configured for SQLJDBCDriver)"}, {"R_unexpectedThreadCount", "Thread count is higher than expected."}}; } diff --git a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java index 93bf7c0db..09c3c245e 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java @@ -66,6 +66,10 @@ public abstract class AbstractTest { protected static String[] enclaveAttestationUrl = null; protected static String[] enclaveAttestationProtocol = null; + + protected static String kerberosServer = null; + protected static String kerberosServerPort = null; + protected static String clientCertificate = null; protected static String clientKey = null; protected static String clientKeyPassword = ""; @@ -101,6 +105,7 @@ public abstract class AbstractTest { protected static Connection connectionAzure = null; protected static String connectionString = null; protected static String connectionStringNTLM; + protected static String connectionStringKerberos; protected static ConfidentialClientApplication fedauthClientApp = null; @@ -191,6 +196,9 @@ public static void setup() throws Exception { clientKeyPassword = getConfiguredProperty("clientKeyPassword", ""); + kerberosServer = getConfiguredProperty("kerberosServer", null); + kerberosServerPort = getConfiguredProperty("kerberosServerPort", null); + trustStore = getConfiguredProperty("trustStore", ""); if (!trustStore.trim().isEmpty()) { connectionString = TestUtils.addOrOverrideProperty(connectionString, "trustStore", trustStore); @@ -242,7 +250,7 @@ public static void setup() throws Exception { protected static void setupConnectionString() { connectionStringNTLM = connectionString; - // if these properties are defined then NTLM is desired, modify connection string accordingly + // If these properties are defined then NTLM is desired, modify connection string accordingly String domain = getConfiguredProperty("domainNTLM"); String user = getConfiguredProperty("userNTLM"); String password = getConfiguredProperty("passwordNTLM"); @@ -265,6 +273,14 @@ protected static void setupConnectionString() { connectionStringNTLM = TestUtils.addOrOverrideProperty(connectionStringNTLM, "integratedSecurity", "true"); } + if (null != kerberosServer && null != kerberosServerPort) { + connectionStringKerberos = "jdbc:sqlserver://" + kerberosServer + ":" + kerberosServerPort + ";"; + connectionStringKerberos = TestUtils.addOrOverrideProperty(connectionStringKerberos, "authenticationScheme", "JavaKerberos"); + connectionStringKerberos = TestUtils.addOrOverrideProperty(connectionStringKerberos, "integratedSecurity", "true"); + connectionStringKerberos = TestUtils.addOrOverrideProperty(connectionStringKerberos, "trustServerCertificate", "true"); + connectionStringKerberos = TestUtils.addOrOverrideProperty(connectionStringKerberos, "encrypt", "false"); + } + ds = updateDataSource(connectionString, new SQLServerDataSource()); dsXA = updateDataSource(connectionString, new SQLServerXADataSource()); dsPool = updateDataSource(connectionString, new SQLServerConnectionPoolDataSource()); diff --git a/src/test/java/com/microsoft/sqlserver/testframework/Constants.java b/src/test/java/com/microsoft/sqlserver/testframework/Constants.java index eb387250b..bddba5536 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/Constants.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/Constants.java @@ -24,6 +24,7 @@ private Constants() {} * xAzureSQLDW - - - - For tests not compatible with Azure Data Warehouse * xAzureSQLMI - - - - For tests not compatible with Azure SQL Managed Instance * NTLM - - - - - - - For NTLM tests + * Kerberos - - - - - For Kerberos tests * reqExternalSetup - For tests requiring external setup * clientCertAuth - - For tests requiring client certificate authentication setup * Fedauth - - - - - - For Fedauth tests @@ -39,6 +40,7 @@ private Constants() {} public static final String xAzureSQLDW = "xAzureSQLDW"; public static final String xAzureSQLMI = "xAzureSQLMI"; public static final String NTLM = "NTLM"; + public static final String Kerberos = "Kerberos"; public static final String MSI = "MSI"; public static final String reqExternalSetup = "reqExternalSetup"; public static final String clientCertAuth = "clientCertAuth"; From 5287b048dcd926de2fde56c3331e2dd0d80764c9 Mon Sep 17 00:00:00 2001 From: Terry Chow Date: Wed, 11 Oct 2023 10:10:20 -0700 Subject: [PATCH 3/3] PR comments --- pom.xml | 2 +- .../java/com/microsoft/sqlserver/testframework/Constants.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a2c21f35f..560c76f3b 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ setup (excluded by default) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default testing enabled with SQL Server 2019 (SQLv15) --> - xSQLv12,xSQLv15,NTLM,MSI,reqExternalSetup,clientCertAuth,fedAuth,Kerberos + xSQLv12,xSQLv15,NTLM,MSI,reqExternalSetup,clientCertAuth,fedAuth,kerberos -preview diff --git a/src/test/java/com/microsoft/sqlserver/testframework/Constants.java b/src/test/java/com/microsoft/sqlserver/testframework/Constants.java index bddba5536..d5b475941 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/Constants.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/Constants.java @@ -40,7 +40,7 @@ private Constants() {} public static final String xAzureSQLDW = "xAzureSQLDW"; public static final String xAzureSQLMI = "xAzureSQLMI"; public static final String NTLM = "NTLM"; - public static final String Kerberos = "Kerberos"; + public static final String Kerberos = "kerberos"; public static final String MSI = "MSI"; public static final String reqExternalSetup = "reqExternalSetup"; public static final String clientCertAuth = "clientCertAuth";