JAAS, JNDI, GSSAPI and Active Directory

I have been banging my head on my desk for a few days now, trying to understand what is needed in order to implement Kerberos authentication from a JAAS LoginModule to ActiveDirectory. I can't use the Krb5LoginModule, so I've started writing my own LoginModule. I've got a basic JNDI lookup using 'simple' authentication to work; now I need to use 'GSSAPI' authentication for the Kerberos requirement. I've been all over Google and have yet to find a good, complete example of how to implement GSSAPI when using JNDI to connect to a LDAP (ActiveDirectory) server.

If anyone has a complete, working example that they can share, I would be eternally grateful.

Thanks...

[694 byte] By [jjalenaka] at [2007-10-1 16:55:37]
# 1

An AD sever can be accessed as a regular ldap server. This is a sample of how to add e "description" attribute to an entry using kerberos and gssapi as auth method.

java 1.4 kerberos implementation only have support for des-cbc-crc so use jdk1.5 and des3-cbc-crc insted. In jdk1.5 you can also use "ldaps://ssl-server/" to specify SSL

import javax.naming.*;

import javax.naming.directory.*;

import javax.security.auth.login.*;

import javax.security.auth.Subject;

import java.util.Hashtable;

class GssExample {

public static void main(String[] args) {

// 1. Log in (to Kerberos)

LoginContext lc = null;

try {

lc = new LoginContext(GssExample.class.getName());

lc.login();

} catch (LoginException le) {

System.err.println("Authentication attempt failed" + le);

System.exit(-1);

}

// 2. Perform JNDI work as logged in subject

Subject.doAs(lc.getSubject(), new JndiAction(args));

}

}

/**

* The application must supply a PrivilegedAction that is to be run

* inside a Subject.doAs() or Subject.doAsPrivileged().

*/

class JndiAction implements java.security.PrivilegedAction {

private String[] args;

public JndiAction(String[] origArgs) {

this.args = (String[])origArgs.clone();

}

public Object run() {

performJndiOperation(args);

return null;

}

private static void performJndiOperation(String[] args) {

String dn = "uid=wikm,dc=it,dc=su,dc=se";

// Set up environment for creating initial context

Hashtable env = new Hashtable(11);

env.put(Context.INITIAL_CONTEXT_FACTORY,

"com.sun.jndi.ldap.LdapCtxFactory");

env.put(Context.PROVIDER_URL, "ldap://server-without-ssl:389/");

env.put(Context.PROVIDER_URL, "ldap://server-with-ssl:636/");

env.put(Context.SECURITY_PROTOCOL, "ssl");

env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");

try {

/* Create initial context */

DirContext ctx = new InitialDirContext(env);

ModificationItem[] mods = new ModificationItem[1];

Attribute mod0 = new BasicAttribute("description","Programmer and system developer.");

mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,mod0);

ctx.modifyAttributes(dn, mods);

System.out.println("ATTRIBUTE ADDED: " + mods.toString());

ctx.close();

ctx.close();

} catch (NamingException e) {

System.out.println(e.getMessage());

e.printStackTrace();

}

}

}

gsseg_jaas.conf

GssExample {

com.sun.security.auth.module.Krb5LoginModule

required client=TRUE

useTicketCache="true"

ticketCache="${user.krb5cc}";

};

java -classpath . \

-Djava.security.auth.login.config=gsseg_jaas.conf \

-Djava.security.krb5.conf=krb5.conf \

-Djava.security.manager \

-Djava.security.policy=krb5.policy \

-Duser.krb5cc=$KRB5CCNAME \

GssExample $1

krb5.policy

grant /* GssExample program */ {

/* Principal javax.security.auth.kerberos.KerberosPrincipal "wikm@SU.SE" { */

permission java.security.AllPermission;

permission java.net.SocketPermission "ldap.domain", "connect";

permission java.net.SocketPermission "kerberos.domain", "connect";

permission java.net.SocketPermission "*", "connect";

permission javax.security.auth.AuthPermission "createLoginContext.GssExample";

permission javax.security.auth.AuthPermission "createLoginContext.Mutual";

permission javax.security.auth.AuthPermission "doAs";

permission javax.security.auth.kerberos.ServicePermission

"krbtgt/SU.SE@SU.SE",

"initiate";

permission javax.security.auth.kerberos.ServicePermission

"ldap/ds-master.su.se@SU.SE",

"initiate";

};

Mikael-Wikstroma at 2007-7-11 1:26:42 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 2
I tried your example but it doesn't work for me: Login works well, but GSSAPI complains about no tickets found (strange, since Login used the ticket cache without problems). What can I do?
MarkusKargQUIPSYa at 2007-7-11 1:26:42 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 3

I keep having the same problem - workign against kdc and ldap on Samba-4

It bothers me that simple authentication works with the whole distinguished name

"CN=Administrator,CN=Users,DC=unixqa,dc=com" as principal

while for kerberos I have to use Administrator@UNIXQA.COM - yes in uppercase.

I'll probably post something more substantive - but generally there seems to be a documentation issue here.

tgila at 2007-7-11 1:26:42 > top of Java-index,Security,Other Security APIs, Tools, and Issues...