5

I configured Websphere full (8.5.5.4) to login in with LDAP registry, and set up the authentication and expiration mechanism as "Kerberos and LTPA".

Authentication is working, But when I try to query in ldap with the current user, I get this exception:

Exception:

javax.naming.AuthenticationException: GSSAPI [Root exception is javax.security.sasl.SaslException: GSS initiate failed [Caused by org.ietf.jgss.GSSException, major code: 11, minor code: 0
    major string: General failure, unspecified at GSSAPI level
    minor string: Error: java.lang.Exception: Error: com.ibm.security.krb5.internal.KrbException, status code: 41
    message: Message stream modified]]

KRB Log

[KRB_DBG_KDC] KrbKdcRep:SoapConnectorThreadPool : 0:  WebContainer : 3 >>> KrbKdcRep renewable option does not match: false - true

(When I remove the "renewable" option from krb.conf I can not authenticate to the websphere.)

Servlet:

public class LoginServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String user = request.getParameter("user");
        String pass = request.getParameter("pass");

        try{
            com.ibm.wsspi.security.auth.callback.WSCallbackHandlerFactory factory;
            factory = com.ibm.wsspi.security.auth.callback.WSCallbackHandlerFactory.getInstance();

            WSCallbackHandlerImpl wsCallbackHandler = new WSCallbackHandlerImpl(user,"DOCKER.BC",pass);

            LoginContext loginCtx = new LoginContext("system.DEFAULT", wsCallbackHandler);
            loginCtx.login();

            Subject subject = loginCtx.getSubject();
            com.ibm.websphere.security.auth.WSSubject.setRunAsSubject(subject);

            String seed = Subject.doAs(subject, new LdapSeedAction("CN=root,CN=Users,DC=docker,DC=bc"));

            com.ibm.websphere.security.auth.WSSubject.setRunAsSubject(subject);

            //Extracting kerberosTicket
            KerberosTicket kerberosTicketFromSubject = SubjectHelper.getKerberosTicketFromSubject(subject);
           //The old subject does not have KerberosTicket, so I created a new one and it includes the KerberosTicket
            Subject subject1 = new Subject();
            SubjectHelper.putKerberosTicketToSubject(kerberosTicket, subject1);
            //OK, The subject now contains KerberosTicket
            //Does not work, (this will run at some point in the application)
            String seed = Subject.doAs(subject1, new LdapSeedAction("CN=root,CN=Users,DC=docker,DC=bc"));

        }catch (Exception e){
            System.out.println(e);
        }
    }
}

Search

public class LdapSeedAction implements java.security.PrivilegedAction<String> {
    private static ResourceBundle resourceBundle = ResourceBundle.getBundle("ad-ldap");

    private static final String SEED_ATTRIBUTE = "seed";
    private static final String HOST = resourceBundle.getString("HOSTS");
    private static final String LDAP_BASE_DN = resourceBundle.getString("LDAP_BASE_DN");
    private static final String LDAP_USERS_BASE = resourceBundle.getString("LDAP_USERS_BASE");
    private String distinguishedName;

    public LdapSeedAction(String distinguishedName) {
        this.distinguishedName = distinguishedName;
    }

    private String getProviderUrl() {
        return "ldap://" + HOST + ":389/" + LDAP_BASE_DN;
    }

    public String run() {
        String seed = null;
        Hashtable env = new Hashtable(5);
        String url = getProviderUrl();
        String INITIAL_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
        env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
        env.put(Context.PROVIDER_URL, url);

        //It does not work with GSSAPI, I can not use username and password
        env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
        try {
            //AuthenticationException: GSSException, Message stream modified
            DirContext ctx = new InitialDirContext(env);

            SearchControls sc = new SearchControls();
            sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
            NamingEnumeration<SearchResult> answer;
            answer = ctx.search(LDAP_USERS_BASE, "(userPrincipalName=" + this.distinguishedName + ")", sc);
            if(answer.hasMoreElements()){
                SearchResult user = answer.next();
                seed = user.getAttributes().get(SEED_ATTRIBUTE).toString();
            }
            ctx.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return seed;
    }
}

/etc/krb5.conf

[libdefaults]
    default_realm = DOCKER.BC
    default_checksum = rsa-md5
    default_keytab_name = FILE:/etc/krb5/krb5.keytab
    default_tkt_enctypes = rc4-hmac,des-cbc-md5,des-cbc-crc
    default_tgs_enctypes = rc4-hmac,des-cbc-md5,des-cbc-crc
    forwardable = true
    renewable = true
    noaddresses = true
    clockskew = 300
[realms]
    DOCKER.BC = {
        kdc = samba
        admin_server = samba
        default_domain = samba
    }
[domain_realm]
    .docker.bc = DOCKER.BC
Nickolas
  • 101
  • 6
  • 1
    I don't know what's wrong with your code, but I would start by testing if the LDAP server even supports GSSAPI clients. $ kinit $ ldapsearch -Y GSSAPI -H ldap://HOST:389/ -b LDAP_BASE_DN userPrincipalName=foo See: http://security.stackexchange.com/questions/65093/how-to-test-ldap-that-authenticates-with-kerberos – anttix Feb 20 '17 at 03:33
  • @anttix Actually, this was one of the problems, now this command is executed successfully. Another problem I identified was that Subject did not contain KerberosTicket, so I created a new Subject and added KerberosTicket to private credentials. The error I get now in java is: com.ibm.security.krb5.internal.KrbException, status code: 41 message: Message stream modified]] Kerberos log: [KRB_DBG_KDC] KrbKdcRep renewable option does not match: false - true My krb.conf file has the renewable = true option in libdefaults, when I remove this option I can not authenticate in the was. – Nickolas Feb 20 '17 at 13:55

0 Answers0