Java – try to configure LDAP as a JNDI resource in Tomcat

I have an LDAP server that I use to authenticate users in the Tomcat web application I'm using jndirealm, which is configured in the context file, which works well

I also need to search for user information in LDAP I've figured out how to do this using the "JNDI method", and I make it work outside Tomcat by creating my own JNDI context using a hash table However, instead of configuring the JNDI attribute in the code, I want to create a JNDI rsource in the context file next to the real configuration

I think I will 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 Tomcat tells me that the resource cannot be created or when I try to initialize with something like this:

Context initctx = new InitialContext();
DirContext ctx = (DirContext) initctx.lookup("java:comp/env/ldap");

Tomcat told me "cannot create resource instance" I'm still on my web The correct resource ref is added to the XML file, so I don't think that's the problem

Since LDAP is used with the JNDI method, I assume it should be able to be configured as a resource, right? What did I miss?

Solution

This answer is a little late, but it may be useful to other users It is based on ejp's answer

The following solutions were tested on Apache Tomcat 7 If necessary, you can replace ldapcontext with dircontext

Create an objectfactory

Create a class that implements objectfactory to instantiate 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;
    }
}

Define your resources

Add the following to the context XML, reference the factory and define the value to create an 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 the asset, consider updating the objectfactory created above to read these new attributes / values

Use your resources

Inject your resources wherever you need them:

@Resource(name = "ldap/LdapResource")
private LdapContext bean;

Or refer to:

Context initialContext = new InitialContext();
LdapContext ldapContext = (LdapContext)
    initialContext.lookup("java:comp/env/ldap/LdapResource");

See more

The Apache Tomcat documentation explains how to add custom resource factories

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>