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]

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";
};