首页 > 解决方案 > Kerberos cannot use ticket cache in Java code

问题描述

I had a service which tries to use kerberos ticket cache but I always get error like Caused by: java.lang.RuntimeException: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos credentails).

If I do not use ticket caching, everything seems just works. Below is the parameters I use to specify ticket caching.

            loginContext = new LoginContext("", null, null, new Configuration()
            {
                @Override
                public AppConfigurationEntry[] getAppConfigurationEntry(String name)
                {
                    Map<String, String> options = new HashMap<>();
                    options.put("refreshKrb5Config", "true");
                    options.put("doNotPrompt", "true");
                    if (LOG.isDebugEnabled()) {
                        options.put("debug", "true");
                    }
                    if (config.getKeytab() != null) {
                        options.put("keyTab", config.getKeytab().getAbsolutePath());
                    }
                    options.put("isInitiator", "false");
                    options.put("useKeyTab", "true");
                    options.put("principal", servicePrincipal);
                    //options.put("storeKey", "true");
                    
                    //manually specify /tmp/krb5cc_ServiceUid for ticketCache
                    options.put("ticketCache", config.getCredentialCache().getAbsolutePath());
                    options.put("useTicketCache", "true");
                    options.put("renewTGT", "true");

                    return new AppConfigurationEntry[] {new AppConfigurationEntry(Krb5LoginModule.class.getName(), REQUIRED, options)};
                }
            });
            loginContext.login();

Then I use below code snippets to get the credential:

            String name = loginContext.getSubject().getPrincipals().iterator().next().getName();
            serverCredential = doAs(loginContext.getSubject(), () -> gssManager.createCredential(
                    //gssManager.createName(config.getServiceName() + "@" + hostname, GSSName.NT_HOSTBASED_SERVICE),
                    gssManager.createName(name, GSSName.NT_HOSTBASED_SERVICE),
                    //INDEFINITE_LIFETIME,
                    DEFAULT_LIFETIME,
                    /*new Oid[] {
                            new Oid("1.2.840.113554.1.2.2"), // kerberos 5
                            new Oid("1.3.6.1.5.5.2") // spnego
                    },*/
                    new Oid("1.2.840.113554.1.2.2"),
                    ACCEPT_ONLY));

Is there anything wrong with above code snippets? I also confirmed that /tmp/krb5cc_ServiceUid indeed exists.

Thank you

标签: javakerberosgssapi

解决方案


推荐阅读