I have an ldap server that I'm using to authenticate users within a tomcat web application. I'm using the JNDIRealm and it's configured within a context file and this works great.
I'll also need to search the ldap for user information. I've figured out how to do this with the "jndi method" and I have it working fine outside of tomcat by creating my own jndi context using a hashtable. However, instead of configuring the jndi properties in code, I'd like to create a JNDI Rsource in my context file right next to the Realm configuration.
I'm thinking I would do something like this:
<Resource
name="ldap"
auth="Container"
type="com.sun.jndi.ldap.LdapCtxFactory"
java.naming.factory.initial="com.sun.jndi.ldap.LdapCtxFactory"
java.naming.provider.url="ldap://localhost:389"
java.naming.security.authentication="simple"
java.naming.security.principal="uid=rjcarr,dc=example"
java.naming.security.credentials="abc123"
/>
But either tomcat tells me the resource can't be created or when I try to initialize it with something like this:
Context initctx = new InitialContext();
DirContext ctx = (DirContext) initctx.lookup("java:comp/env/ldap");
Tomcat tells me the "Cannot create resource instance". I've also added the correct resource-ref in my web.xml file, so I don't think that's the problem.
Since LDAP is being used with the JNDI method I'm assuming it should be able to be configured as a Resource, right? What am I missing?
This answer is a bit late, but probably it'll be useful for other users. It's based on EJP's answer .
The following solution was tested on Apache Tomcat 7 .
If you need, you can replace LdapContext
with DirContext
.
Create a class which implements ObjectFactory
to instantiate a LdapContext
:
public class LdapContextFactory implements ObjectFactory {
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable<?, ?> environment) throws Exception {
Hashtable<Object, Object> env = new Hashtable<Object, Object>();
Reference reference = (Reference) obj;
Enumeration<RefAddr> references = reference.getAll();
while (references.hasMoreElements()) {
RefAddr address = references.nextElement();
String type = address.getType();
String content = (String) address.getContent();
switch (type) {
case Context.INITIAL_CONTEXT_FACTORY:
env.put(Context.INITIAL_CONTEXT_FACTORY, content);
break;
case Context.PROVIDER_URL:
env.put(Context.PROVIDER_URL, content);
break;
case Context.SECURITY_AUTHENTICATION:
env.put(Context.SECURITY_AUTHENTICATION, content);
break;
case Context.SECURITY_PRINCIPAL:
env.put(Context.SECURITY_PRINCIPAL, content);
break;
case Context.SECURITY_CREDENTIALS:
env.put(Context.SECURITY_CREDENTIALS, content);
break;
default:
break;
}
}
LdapContext context = new InitialLdapContext(env, null);
return context;
}
}
Add the following to your context.xml
, referencing the factory and defining the values to create a LdapContext
instance:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
...
<Resource name="ldap/LdapResource" auth="Container"
type="javax.naming.ldap.LdapContext"
factory="com.company.LdapContextFactory"
singleton="false"
java.naming.factory.initial="com.sun.jndi.ldap.LdapCtxFactory"
java.naming.provider.url="ldap://127.0.0.1:389"
java.naming.security.authentication="simple"
java.naming.security.principal="username"
java.naming.security.credentials="password" />
</Context>
If you need to add more attributes/values to your resource, consider updating your ObjectFactory
created above to read these new attributes/values.
Inject your resource wherever you need:
@Resource(name = "ldap/LdapResource")
private LdapContext bean;
Or look it up:
Context initialContext = new InitialContext();
LdapContext ldapContext = (LdapContext)
initialContext.lookup("java:comp/env/ldap/LdapResource");
Apache Tomcat's documentation explains how to add custom resource factories .
You're making it up. The type of a Tomcat resource must be a class that implements javax.naming.spi.ObjectFactory. See the Tomcat documentation for custom resources.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.