2

Using this example, almost get my conection working

http://blogs.nologin.es/rickyepoderi/index.php?/archives/105-Oracle-Driver-and-Kerberos.html

but after enable kerberos cache and debug it's getting my principal name correctly and credentials succesful there's an error related with ticket.

ticket is generated with okinit (oracle kinit from oracle 12)

Exception in thread "main" java.sql.SQLRecoverableException: Error de E/S: The service in process is not supported. Failure unspecified at GSS-API level (Mechanism level: Generic error (description in e-text) (60) - ASN.1 unexpected field number)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:743)
    at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:666)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:566)
    at java.sql.DriverManager.getConnection(DriverManager.java:571)
    at java.sql.DriverManager.getConnection(DriverManager.java:187)
    at JdbcThin.main(JdbcThin.java:39)
Caused by: oracle.net.ns.NetException: The service in process is not supported. Failure unspecified at GSS-API level (Mechanism level: Generic error (description in e-text) (60) - ASN.1 unexpected field number)
    at oracle.net.ano.AuthenticationService.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at oracle.net.ano.AuthenticationService.e(Unknown Source)
    at oracle.net.ano.Ano.negotiation(Unknown Source)
    at oracle.net.ns.NSProtocol.connect(NSProtocol.java:293)
    at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1452)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:496)
    ... 6 more
Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Generic error (description in e-text) (60) - ASN.1 unexpected field number)
    at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:710)
    at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248)
    at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
    ... 14 more
Caused by: KrbException: Generic error (description in e-text) (60) - ASN.1 unexpected field number
    at sun.security.krb5.KrbApRep.(KrbApRep.java:126)
    at sun.security.krb5.KrbApRep.(KrbApRep.java:102)
    at sun.security.krb5.KrbApRep.(KrbApRep.java:75)
    at sun.security.jgss.krb5.AcceptSecContextToken.(AcceptSecContextToken.java:89)
    at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:696)
    ... 16 more
Caused by: KrbException: Identifier doesn't match expected value (906)
    at sun.security.krb5.internal.APRep.init(APRep.java:92)
    at sun.security.krb5.internal.APRep.(APRep.java:75)
    at sun.security.krb5.KrbApRep.(KrbApRep.java:116)
    ... 20 more

I'm using a java 7 but there's no problem in use another one. Is there a way to read ticket correctly with a jvm (see kinit from jdk do not create a correct ticket too)

2 Answers 2

1

I'm sharing this piece of code which has been working for me. Have you set the location of the kerberos cache file?

OracleDriver driver = new OracleDriver();
Properties prop = new Properties();

prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_SERVICES,
  "("+AnoServices.AUTHENTICATION_KERBEROS5+")");  
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5_MUTUAL,
  "true");    

/* If you get the following error [Unable to obtain Principal Name for 
 * authentication] although you know that you have the right TGT in your
 * credential cache, then it's probably because the JVM can't locate your
 * cache.
 * For example, here my credential cache is
 *        C:\Documents and Settings\Jean de Lavarene\krb5cc
 * because when I run klist I get the following:
 *   > ./klist
 *   Ticket cache: FILE:C:\Documents and Settings\Jean de Lavarene\krb5cc
 *   Default principal: [email protected]
 *
 *   Valid starting     Expires            Service principal
 *   06/21/16 13:23:02  06/21/16 23:23:02  krbtgt/[email protected]
 *   renew until 06/21/16 13:23:02
 * This isn't the default location, so I need to provide the location. Note
 * that the default location on windows is "C:\Documents and Settings\krb5cc_username".
 */
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5_CC_NAME,
  "C:\\Documents and Settings\\Jean de Lavarene\\krb5cc");
Connection conn  = driver.connect(url,prop);
String auth = ((OracleConnection)conn).getAuthenticationAdaptorName();
System.out.println("Authentication adaptor="+auth);
Sign up to request clarification or add additional context in comments.

2 Comments

I have cache added (as I say, it reads credentials from it correctly) Are you using this code against a oracle 11 or lower?. Problems comes with oracle 12 which needs its own implementation of kinit (okinit)
This was with the 11.2 version of the Oracle Database. I'll give it a try using 12.
0

This is solution for Win10/Win2019 where Credential Guard is in place (the trick with AllowTgtSessionKey=1 does not work anymore).

Kerberos ticket has to be generated using SSPI API. Works since JDK 11.0.10.

import java.sql.ResultSet;
import java.sql.Statement;

import java.util.Properties;

import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;

import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleConnectionBuilder;
import oracle.jdbc.pool.OracleDataSource;
import oracle.net.ano.AnoServices;

public class Test3 {
    String username = System.getProperty("user.name");
    String domain = System.getenv("USERDNSDOMAIN");
    String url = "jdbc:oracle:thin:@//dbatdb1:1521/TEST_1";

    public Test3() {
    }

    public void doit() throws Exception
    {
        // set env. variable to enable tracing in sspi_bridge.dll
        // set SSPI_BRIDGE_TRACE=1
        //System.setProperty("oracle.jdbc.Trace", "true");
        //System.setProperty("sun.security.krb5.debug", "true");
        //System.setProperty("sun.security.spnego.debug", "true");
        //System.setProperty("sun.security.jgss.debug", "true");
        //System.setProperty("java.security.debug", "true");
        //System.setProperty("sun.security.nativegss.debug", "true");

        //System.setProperty("java.security.krb5.conf", "D:/oracle/WINDOWS.X64_193000_client_home/network/admin/krb5.conf");
        System.setProperty("sun.security.jgss.native", "true");
        System.setProperty("sun.security.jgss.lib", "sspi_bridge.dll");

        Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
        GSSManager manager = GSSManager.getInstance();

        GSSName srcName = manager.createName(username + "@" + domain, GSSName.NT_USER_NAME);
        GSSCredential cred = manager.createCredential(srcName
                , GSSCredential.DEFAULT_LIFETIME
                , krb5Oid, GSSCredential.INITIATE_ONLY);

        Properties prop = new Properties();
        prop.setProperty(AnoServices.AUTHENTICATION_PROPERTY_SERVICES, "(" + AnoServices.AUTHENTICATION_KERBEROS5 + ")");
        prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_SERVICES,"( " + AnoServices.AUTHENTICATION_KERBEROS5 + " )");
        prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5_MUTUAL, "true");

        OracleDataSource ods = new OracleDataSource();
        ods.setURL(url);
        ods.setConnectionProperties(prop);
        OracleConnectionBuilder builder = ods.createConnectionBuilder();
        OracleConnection conn = builder.gssCredential(cred).build();
        
        String auth = ((OracleConnection)conn).getAuthenticationAdaptorName();
        System.out.println("Authentication adaptor="+auth);

        String sql = "select user from dual";
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        while (rs.next())
            System.out.println("whoami: " + rs.getString(1));

        conn.close();
    }

    public static void main(String[] args) {
        Test3 test = new Test3();
        try {
            test.doit();
            System.out.println("Done");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.