MSSQL Server with Integrated Security and Kerberos Authentication for Mac

Last updated: July 14, 2025

If your application runs on a Linux or Windows-based intranet, you can use the integrated authentication to access your database. Integrated security uses the identity established on the operating system thread to access MSSQL Server.

Kerberos is an authentication protocol that works based on tickets to provide strong authentication for client/server applications by using secret-key cryptography. The Kerberos authentication protocol does not store passwords locally or send them over the Internet.

Before you begin

Procedure

1

Configuration

1. From the command line, enter ktutil to launch the utility.

2. Enter the following commands: Note: Replace <username> with the Kerberos principal user.

add_entry -password -p <username> -k 1 -e des3-cbc-sha1-kd add_entry -password -p <username> -k 1 -e arcfour-hmac-md5 add_entry -password -p <username> -k 1 -e des-hmac-sha1 add_entry -password -p <username> -k 1 -e des-cbc-md5 add_entry -password -p <username> -k 1 -e des-cbc-md4

3. When prompted, enter the password for the principal user.

4. Enter the following command to create the keytab file:

wkt /path/to/<username>.keytab

5. Enter q to quit the ktutil utility.

6. Check the registered user in the keytab file by running:

klist -k /path/to/<username>.keytab

7. Create the /etc/krb5.conf file. Example [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] clockskew = 6000 forwardable = true default_realm = MYDOMAIN.COM default_ccache_name = /path/to/krb5cc [realms] MYDOMAIN.NET = { kdc = domainserver.mydomain.com admin_server = domainserver.mydomain.com } [domain_realm] .MYDOMAIN.COM = MYDOMAIN.COM MYDOMAIN.COM = MYDOMAIN.COM

Create the /etc/JDBCDriverLogin.conf file. Example SQLJDBCDriver { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true useTicketCache=true storeKey=true keyTab="/path/to/<keytabname>.keytab" principal="<AD username>@MYDOMAIN.COM"; }; KrbLogin { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="/path/to/<username>.keytab" useTicketCache=true debug=true; };

Note: For more information, see the Use Active Directory authentication with SQL Server on Linux page.

2

Configuring the Liquibase and Kerberos connection

1. Run the kinit command to obtain and cache Kerberos ticket-granting tickets. To verify and list the new information from the krb5cc file, you can also run the klist command. For example:

kinit lbuser Password for lbuser@MYDOMAIN.COM: klist Ticket cache: FILE:/temp/krb5cc Default principal: @MYDOMAIN.COM

2. Specify the database URL in the liquibase.properties file (defaults file), along with other properties you want to set a default value for. Liquibase does not parse the URL. You can either specify the full database connection string or specify the URL using your database's standard connection format:

url: jdbc:sqlserver://<host name or endpoint>:1433;IntegratedSecurity=true;databaseName=<database name>;authenticationScheme=JavaKerberos;useTicketCache=true;doNotPrompt=true;moduleBanner=false;ServerSpn=MSSQLSvc/<hostname><FQDN>:1433@MYDOMAIN.COM;

3. Include the following JAVA_OPTS arguments to ensure you have all the necessary Java arguments.

JAVA_OPTS="-Djava.security.krb5.conf=/path/to/krb5.conf -Dsun.security.krb5.debug=true -Dcom.sun.security.auth.module.Krb5LoginModule=required -DuseTicketCache=true -Djava.security.auth.login.config=/path/to/JDBCDriverLogin.conf"

4. Run the liquibase status command to ensure the connection works.

JAVA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true -Dcom.sun.security.auth.module.Krb5LoginModule=required -DuseTicketCache=true -Djava.security.auth.login.config=/etc/JDBCDriverLogin.conf" liquibase status --verbose

5. (Optional) If you want to use the SQLCMD native executor with Kerberos, you must first set the KRB5CCNAME environment variable

export KRB5CCNAME=<path to ticket file>

Then run Liquibase:

KRB5CCNAME=<path to ticket file> JAVA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true -Dcom.sun.security.auth.module.Krb5LoginModule=required -DuseTicketCache=true -Djava.security.auth.login.config=/etc/JDBCDriverLogin.conf" liquibase status --verbose

Sample output

Starting Liquibase at 14:56:40 Liquibase Version: 4.5.0 Liquibase Community 4.5.0 >>>KinitOptions cache name is /tmp/krb5cc_1000 >>> KeyTabInputStream, readName(): MYDOMAIN.COM >>> KeyTabInputStream, readName(): lbuser >>> KeyTab: load() entry length: 68; type: 16 >>> KeyTabInputStream, readName(): MYDOMAIN.COM >>> KeyTabInputStream, readName(): lbuser >>> KeyTab: load() entry length: 60; type: 23 >>> KeyTabInputStream, readName(): MYDOMAIN.COM >>> KeyTabInputStream, readName(): lbuser >>> KeyTab: load() entry length: 52; type: 8 >>> KeyTabInputStream, readName(): MYDOMAIN.COM >>> KeyTabInputStream, readName(): lbuser >>> KeyTab: load() entry length: 52; type: 3 >>> KeyTabInputStream, readName(): MYDOMAIN.COM >>> KeyTabInputStream, readName(): lbuser >>> KeyTab: load() entry length: 52; type: 2 Looking for keys for: MYDOMAIN.COM Java config name: /etc/krb5.conf Loading krb5 profile at /etc/krb5.conf ... ... >>> DEBUG: ----Credentials---- client: MYDOMAIN.COM server: MSSQLSvc/xxx:1433@MYDOMAIN.COM ticket: sname: MSSQLSvc/xxx:1433@MYDOMAIN.COM startTime: 1635951401000 endTime: 1635987401000 ----Credentials end---- Subject is readOnly;Kerberos Service ticket not stored Using builtin default etypes for default_tgs_enctypes default etypes for default_tgs_enctypes: 18 17 20 19 16 23. >>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType >>> CksumType: sun.security.krb5.internal.crypto.HmacMd5ArcFourCksumType >>> EType: sun.security.krb5.internal.crypto.ArcFourHmaEType >>> KrbKdcReq send: kdc=MYDOMAIN.COM TCP:88, timeout=30000, number of retries =3, #bytes=1482 >>> KDCCommunication: kdc=MYDOMAIN.COM TCP:88, timeout=30000,Attempt =1, #bytes=1482 >>>DEBUG: TCPClient reading 1442 bytes >>> KrbKdcReq send: #bytes read=1442 >>> KdcAccessibility: remove MYDOMAIN.COM >>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacShaEType >>> KrbApReq: APOptions are 00100000 00000000 00000000 00000000 >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacShaEType Krb5Context setting mySeqNumber to: 00000 Created InitSecContextToken: 0000: 01 00 6E 82 0B 91 30 82 0B 8D A0 03 02 01 05 A1 ..n...0......... 0010: 03 02 01 0E A2 07 03 05 00 20 00 00 00 A3 82 04 ......... ...... 0020: EA 61 82 04 E6 30 82 04 E2 A0 03 02 01 05 A1 13 .a...0.......... 0030: 1B 11 4C 42 2D 43 53 2E 44 41 54 49 43 41 4C 2E ..MYDOMAIN. 0040: 4E 45 54 A2 3D 30 3B A0 03 02 01 00 A1 34 30 32 com.=0;......402 0050: 1B 08 4D 53 53 51 4C 53 76 63 1B 26 6D 73 73 71 ..MSSQLSvc.&mssq ... Entered Krb5Context.initSecContext with state=STATE_IN_PROCESS >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacShaEType Krb5Context setting peerSeqNumber to: 1481374XX username@jdbc:sqlserver://xxx:1433;maxResultBuffer=-1; sendTemporalDataTypesAsStringForBulkCopy=true;delayLoadingLobs=true; useFmtOnly=false;useBulkCopyForBatchInsert=false;cancelQueryTimeout=-1;sslProtocol=TLS; jaasConfigurationName=SQLJDBCDriver;statementPoolingCacheSize=0;serverPreparedStatementDiscardThreshold=10; enablePrepareOnFirstPreparedStatementCall=false;fips=false;socketTimeout=0;authentication=NotSpecified; authenticationScheme=JavaKerberos;xopenStates=false;sendTimeAsDatetime=true;trustStoreType=JKS;trustServerCertificate=false; TransparentNetworkIPResolution=true;serverSpn=MSSQLSvc/xxx:1433@MYDOMAIN.COM;serverNameAsACE=false;sendStringParametersAsUnicode=true; selectMethod=direct;responseBuffering=adaptive;queryTimeout=-1;packetSize=8000;multiSubnetFailover=false;loginTimeout=15;lockTimeout=-1; lastupdate-count=true;encrypt=false;disableStatementPooling=true;databaseName=WF_DEV;columnEncryptionSetting=Disabled;applicationName=Microsoft JDBC Driver for SQL Server; applicationIntent=readwrite; is up to date Liquibase command 'status' was executed successfully.

MSSQL Server with Integrated Security and Kerberos Authentication for Mac - Liquibase