Skip to content

Kerberos constrained delegation and connections pool.  #607

@krlm

Description

@krlm

Driver version or jar name

6.2.2-jre8

SQL Server version

2016

Client operating system

Linux, Ubuntu 18.04 (same problem on 16.10)

Java/JVM version

Java(TM) SE Runtime Environment (build 1.8.0_162-ea-b03), Oracle

Table schema

Not relevant, using SELECT SYSTEM_USER query

Problem description

I'm trying to use mssql-jdbc in a Spring boot application with Kerberos authentication. It works fine when I'm using unconstrained mode, (I guess it's because tickets are renewable then) but when I switch to constrained delegation mode then only first iteration of this loop is passing, next iteration is throwing following exception:

java.lang.IllegalStateException: This credential is no longer valid
    at sun.security.jgss.GSSCredentialImpl.getElement(GSSCredentialImpl.java:549) ~[na:1.8.0_162-ea]
    at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:200) ~[na:1.8.0_162-ea]
    at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179) ~[na:1.8.0_162-ea]
    at com.microsoft.sqlserver.jdbc.KerbAuthentication.intAuthHandShake(KerbAuthentication.java:163) ~[mssql-jdbc-6.2.2.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.KerbAuthentication.GenerateClientContext(KerbAuthentication.java:401) ~[mssql-jdbc-6.2.2.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:4049) ~[mssql-jdbc-6.2.2.jre8.jar:na]
    at   
    ...
    at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:569) ~[mssql-jdbc-6.2.2.jre8.jar:na]
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:310) ~[tomcat-jdbc-8.5.23.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735) ~[tomcat-jdbc-8.5.23.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667) ~[tomcat-jdbc-8.5.23.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482) ~[tomcat-jdbc-8.5.23.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) ~[tomcat-jdbc-8.5.23.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) ~[tomcat-jdbc-8.5.23.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) ~[tomcat-jdbc-8.5.23.jar:na]
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) ~[spring-jdbc-4.3.13.RELEASE.jar:4.3.13.RELEASE

when I comment out fragments responsible for disposing credentials in mssql-jdbc, here and here it works fine, just like in unconstrained mode.

Expected behaviour and actual behaviour

Currently valid tickets (with init lifetime > 0) are disposed just right after the connection is established. I'd expect that valid Kerberos ticket can be reused for establishing connections inside connection pool, regardless it's constrained or unconstrained mode (I guess renewing them is a non-zero operation).

However, I'm not sure if it's right place to address this issue - I'm not from Java-land, just building some PoC - but I took ADO.NET SqlClient as reference which does handle impersonation and connection pooling.

Repro code

Will try to provide some small repro basing on mssql-jdbc constrained example later. (I guess adding a loop over connect method will result in the same issue, will check that).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions