jdbcactive-directory

Cannot login with Kerberos principal not_used, check your credentials


I have a Tomcat application running on a RHEL9 host that is trying to connect to a Windows Server running MSSQL using integrated authentication via a JDBC connection on JDK 8. I've thoroughly reviewed the configuration, but I can't determine why I'm consistently encountering this error when the application starts.

ERROR - failed to connect to DB, reason is probably not the database absence. cause: Cannot login with Kerberos principal not_used, check your credentials. Kerberos Login failed: Integrated authentication failed. ClientConnectionId

I have supplied a Jaas Config to the JVM with these settings via setenv.sh export CATALINA_OPTS="$CATALINA_OPTS -Djava.security.auth.login.config=/opt/tomcat/bin/jaas.conf -Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.debug=all"

My JaaS config looks like this:

 SqlJaasConf {
      com.sun.security.auth.module.Krb5LoginModule required
      useKeyTab=true
      keyTab="/etc/krb5.keytab"
      principal="DBUser@TEST.CORP"
      doNotPrompt=true
      storeKey=true
      useTicketCache=false;
    };

My krb5.conf on my RHEL server file looks like this:

[logging]
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

[libdefaults]
    default_realm = TEST.CORP
    dns_lookup_realm = false
    dns_lookup_kdc = false
    ticket_lifetime = 30d
    renew_lifetime = 30d
    rdns = false
    forwardable = true
    udp_preference_limit = 0
    rdns = false
    default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac
    default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac
    permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac

[realms]
TEST.CORP = {
     kdc = 172.31.82.203
     admin_server = 172.31.82.203
 }

[domain_realm]
.test.corp = TEST.CORP
test.corp = TEST.CORP

I can resolve the domains in each host and I have firewall connectivity between them. Also checked that I have a kerberos ticket.

Ticket cache: KCM:0
Default principal: DBUser@TEST.CORP

Valid starting       Expires              Service principal
09/02/2024 21:54:56  10/02/2024 21:54:56  krbtgt/TEST.CORP@TEST.CORP
    renew until 10/02/2024 21:54:56

Also confirmed I have a Service Principle on the Windows AD box.

C:\Users\Administrator>setspn -L DBUser
Registered ServicePrincipalNames for CN=DBUser,CN=Users,DC=test,DC=corp:
        MSSQLSvc/ip-172-31-18-241.ec2.internal:1433

My connection string looks like this:

jdbc:sqlserver://172.31.23.171:1433;databaseName=master;integratedSecurity=true;authenticationScheme=JavaKerberos;ServerSpn=MSSQLSvc/ip-172-31-18-241.ec2.internal:1433;jaasLoginConfigName=SqlJaasConf;realm=TEST.CORP

Few things I have done:

  1. I Installed sqlcmd and confirm that I can use integrated auth by doing the following sqlcmd -S 172.31.23.171 -d master -G -C and can login and run SQL Commands.
  2. I also installed (https://github.com/julianhyde/sqlline) to try and troubleshoot the JDBC connection outside my app. Made sure to add in the jass auth jvm args in the JAVA_OPTS variable. When I add in the domain credentials to the JDBC connection string, it will work like this.

!connect jdbc:sqlserver://172.31.23.171:1433;databaseName=master;integratedSecurity=true;authenticationScheme=JavaKerberos;ServerSpn=MSSQLSvc/ip-172-31-18-241.ec2.internal:1433 DBUser@TEST.CORP ""

If I remove the creds, it fails.

What is going on here? How do I debug?


Solution

  • SPN value MSSQLSvc/ip-172-31-18-241.ec2.internal:1433 is not compliant with your infrastructure, you try to access TEST.CORP domain, the SPN you want to access should have TEST.CORP FQDN extension such as MSSQLSvc/SQL1.TEST.CORP:1433 where SQL1 should be the hostname.

    The ticket you have seems to be the Ticket Granting Ticket (TGT). Your program now should request a TGS (Ticket Granting Service) ticket using the TGT, but since the SPN is problematic, it can not.

    Generally Kerberos works over DNS, so it is better that your code should connect to a DNS FQDN instead of an IP address.

    You can check the Windows side of the connection on the Security event Logs of the domain controller to which your code tries to get a TGS ticket. You may also enable Kerberos Logging via ref: https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/enable-kerberos-event-logging