Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to query LDAP and authenticate users

Posted on 2004-10-27
38
Medium Priority
?
1,077 Views
Last Modified: 2013-11-24
I dont have much experience in Java.
Need to write a java app to authenticate users coming into my web page by querying ldap.
I have a login.jsp that accepts username/password, need direction on writing all other classes to authenticate users and display authenticated users username on firstpage.html
Thank you!


0
Comment
Question by:makam_75
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 15
  • 12
  • 10
  • +1
38 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 12424870
What container are you using?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12424881
0
 

Author Comment

by:makam_75
ID: 12425002
SunOne is the webserver. I was looking for sample code.
Thanks.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 13

Accepted Solution

by:
petmagdy earned 2000 total points
ID: 12425194
First u must have a Directory server like active Directory, or Sun One Directory Server or OpenLDAP (openldap is open source), u can download it from www.openldap.org

then here is a sample authenticate function:

import java.util.Hashtable;
import java.util.Enumeration;

import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.naming.directory.*;

  public boolean authenticateUser(String username, String password) throws NamingException
  {
    Hashtable env = new Hashtable(5, 0.75f);

    env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");

    /* Specify host and port to use for directory service */
    env.put(Context.PROVIDER_URL, "ldap://LDAP_SERVER:389");

    env.put(Context.SECURITY_AUTHENTICATION, Simple);
    env.put(Context.SECURITY_PRINCIPAL, "uid=" +username +", ou=users,o=myOrganization, dc=mydomain,dc=com");
    env.put(Context.SECURITY_CREDENTIALS, password);

    try
    {
        /* get a handle to an Initial DirContext */
        DirContext ctx = new InitialDirContext(env);

            //Authenticated
        return true;
    }
    catch (javax.naming.AuthenticationException ae)
    {
      //Authentication failure
        return false;
    }
    catch (NamingException e)
    {
      return false;
    }
  }
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12425200
>>I was looking for sample code

This kind of thing should in theory require little code since the functionality is provided declaratively. It will be more a question of putting together the right config files for your container
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12425229
just a little correction to my code:

this line:
  env.put(Context.SECURITY_AUTHENTICATION, Simple);

is offcourse meant to be:

  env.put(Context.SECURITY_AUTHENTICATION, "simple");
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12425254
>>then here is a sample authenticate function:

That's not really right. All that context related stuff should have been set up before authentication is attempted. An authenticate function should really only get the context and do a lookup
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12425349
CHEJ

this is how to do LDAP programatic authentication, I meant to provide a sample not exact function implementation, althought this is code is right if the users are located at the orgainzation unit: ou=users,o=myOrganization, dc=mydomain,dc=com,

I am not refering to the Decalarative or JAAS way
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12425412
>>this is how to do LDAP programatic authentication

Even then it's looking a bit iffy for the reasons i've given - the environment should already be there - even if it was done programmatically

>>am not refering to the Decalarative or JAAS way

The idea is to let the container do as much work as possible, declaratively. Such programmatic code that there is will simply input the credentials and receive the result
0
 

Author Comment

by:makam_75
ID: 12425556
Hello petmagdy.
Not sure the need for setting up a directory server.
I already have LDAP set up in my company. Eg. If I telnet to any m/c in the network, I am able to run an ldapsearch command. Does this mean the above code will compile as is?

Or do you mean to say I need to have my own instance of directory server running on the host were I have my web page that authenticates users? Guess I am not clear on it because I do not have understanding of the whole picture.

Like I mentioned before, I am new to this, so I will be using any code as is. I do have my organization unit as ou=users,o=myOrganization, dc=mydomain,dc=com. Please let me know if there are any other concerns.
Thankyou!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12425592
You need to configure the app server to use the existing LDAP. See the container docs
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12425606
CHEJ
I am not in favorate of dwelling arround a point
when refering to the programatic LDAP authenitcation the statment u say

>> An authenticate function should really only get the context and do a lookup

This statment is not accurate Authentication is not lookup on the user in LDAP, it is challenging the User/Password againist the Directory server this achieved by 2 ways:

First way: lookup on the user object in the DS and if found use the DS irreversable encryption technique to decrypt the password and validate it againist the savied in database

Second way: get an LDAP context if success then the user is authented as I provided in the sample code

bye the way Active directory only accepts the second way
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12425649
no I meant to use an existing available Directory server (LDAP server), so u provide the Host name of this server in the LDAP url (ldap://servername:389)

But if the organization will not allow u to test on its running Production LDAP server u can easly make ur own instance on ur machine
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12425745
>>This statment is not accurate Authentication is not lookup on the user in LDAP

>>First way: lookup on the user object in the DS and if found ...

?

makam_75, petmagdy's is a way of doing this programmatically although i'm not convinced it's the best way
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12425825
CEHJ,

I know Recently JAAS became the best way to implement J2EE application security, but as a first step for makam to understand the foundation of this is to concentrate on JNDI and LDAP concepts first that is better before going for more advanced techniques

By the way not all cases the decalrative is the best, in one of the projects I was involved in, when users in a single ou reached more than 60K users declarative costs 4 minutes to authenticate the user while programatic did it in 3 seconds

cheers ;)
0
 

Author Comment

by:makam_75
ID: 12425858
Hi all,
I am not looking for the most correct solution for any generic app. I have a small and urgent requirement, and want to get to it in a most efficient time frame. As long as it works and no cons associated with the method, I am ok in hardcoding some data.  
Petmagdy,
I will have to find out the ldap server name (production and test) from our admin. Are there any other questions I should be asking? If you know a beginners guide for ldap, can youpass it on to me too.

Appreciate everyones time and help here. Thank you.

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12425904
If you're into getting something running quickly, use petmadgy's suggestion.

>>As long as it works and no cons associated with the method

I'll let petmadgy tell you about the pros and cons ;-)
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12425909
do u have a user/password on this directory server?
if no u need to get one for testing purposes, also u need to know for the users to be authenticated where r they on the Directory server hierarchy for example, their location on active directory maybe something like this:

cn=users, dc=thedomain, dc=com

if other may be look like this:

ou=users, o=orgainizationName, dc=thedomain, dc=com

and the heirarchy can be more complicated than that
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12425929
No CHEJ, I am sure that u always has the best way ;)
0
 

Author Comment

by:makam_75
ID: 12426434
Thanks, I will try and implement this today. will let you know the status by mid day tomorrow. I hope you automatically get notification to updates to this thread.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12426955
We do ;-)
0
 

Author Comment

by:makam_75
ID: 12427792
OK I am getting much earlier.

On command line, a command like this works for me
ldapserach -h "directory.tw.com" -b "ou=people,o=tw.com" "uid=makam"
(So I know that directory name and heirarchy structure are correct. )

So, I tried to implement like this. I hardcoded the userid/password I use to login to our intranet(that they have set up using nsconfig) But get the message "false" which means I was not succesffuly authenticated.

Could it be that the password is stored as encrypted, and the one I am passing is not and so they are not matching?

public class myLDAPProg{
      public myLDAPProg() {
      }
      
      public static void main( String args[]) {
            queryLDAP q = new queryLDAP();
            try {
                        boolean value=q.doAuthenticate("myname","mypass");
                        System.out.println("val is"+ value);
            }
            catch(NamingException e) {}
      }
      
}

      public class queryLDAP{
            public queryLDAP(){
            }
            
            public boolean doAuthenticate(String username, String password) throws NamingException
              {
                  Hashtable env = new Hashtable(5, 0.75f);

                  env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");

                  /* Specify host and port to use for directory service */
                  env.put(Context.PROVIDER_URL, "ldap://directory.tw.com:389");

                  env.put(Context.SECURITY_AUTHENTICATION, "simple");
                  env.put(Context.SECURITY_PRINCIPAL, "uid=" +username +", ou=people,o=tw.com,");
                  env.put(Context.SECURITY_CREDENTIALS, password);

                  try
                  {
                        /* get a handle to an Initial DirContext */
                        DirContext ctx = new InitialDirContext(env);

                          //Authenticated
                        return true;
                  }
                  catch (javax.naming.AuthenticationException ae)
                  {
                    //Authentication failure
                     return false;
                  }
                  catch (NamingException e)
                  {
                    return false;
                  }
              }
             
      }

0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12427860
no u don't need to do thing about the password


1- Please make sure that in ur class path u have the following jars:

jndi.jar
ldap.jar
ldapbp.jar
providerutil.jar

also if still return false please put in the catch exceptions

e.printStackTrace()
0
 

Author Comment

by:makam_75
ID: 12428309
If i did not have the jar files, it would not run, correct?

Anyway , I run the program on command line. I could not locate these jar files under C:\j2sdk1.4.2_06\jre\lib

Also, this does not compile
catch(NamingException e) {
                  System.out.println(e.printStackTrace());
            }
The error is The method println() in the type PrintStream is not applicable for the arguments (void)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12428341
>>I could not locate these jar files under C:\j2sdk1.4.2_06\jre\lib

They won't be there. You need to install J2EE SDK too.

>>
catch(NamingException e) {
               System.out.println(e.printStackTrace());
          }
>>

should be

catch(NamingException e) {
    e.printStackTrace();
}
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12428354
>>You need to install J2EE SDK too.

In fact they may not all be there either. petmagdy will probably know where they all are
0
 

Author Comment

by:makam_75
ID: 12428369
But I am getting a "false" as the output. So it was able to get hold of all jar files is my thinking...
0
 

Author Comment

by:makam_75
ID: 12428395
Thanks, I did  e.printStackTrace(); , but do not see any change in the output.
My o/p is
val isfalse

0
 

Author Comment

by:makam_75
ID: 12428419
Sorry, here is the exception.
javax.naming.InvalidNameException: [LDAP: error code 34 - Invalid DN]
        at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)
        at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)
        at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
        at com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
        at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
        at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
        at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
        at javax.naming.InitialContext.init(Unknown Source)
        at javax.naming.InitialContext.<init>(Unknown Source)
        at javax.naming.directory.InitialDirContext.<init>(Unknown Source)
        at com.synopsys.ldap.queryLDAP.doAuthenticate(queryLDAP.java:44)
        at com.synopsys.ldap.authenticateUser.main(authenticateUser.java:40)
val isfalse

I had'nt recreated the jar file before.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12428426
>>So it was able to get hold of all jar files is my thinking...

Well if it now compiles and runs, then yes ;-)

You'll have to check the directory / your credentials if you're getting an unexpected negative
0
 

Author Comment

by:makam_75
ID: 12428479
OK there was one extra comma, I removed it and it is working!
Hurray!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12428531
Good ;-)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12428571
So my contribution to that was worth 0 points then makam_75?
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12431237
LOOOLLLLL, MAKAM sorry I went to bed during the last comments, time zone difference :)
I think MAKAM, it is time to get also idea about the declarative way of LDAP authentication, I sure CEHJ will help u great deal on that ;)
0
 

Author Comment

by:makam_75
ID: 12436124
CEHJ,
I did value your comments very much!
The reasoning behind my awarding points was I have taken the code from petmagdy "as is" and it is working as a complete solution to the question i listed. so i thought it will not be fair if i dont assign him the complete points.
I appreciate your response. Thanks.

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12436214
>>"as is" and it is working as a complete solution to the question i listed

Err.. apart from the fact that you would not have been able to compile it without my help to the question containing the following:

>>Also, this does not compile
0
 

Author Comment

by:makam_75
ID: 12436466
Sorry I overlooked that. I will remember to be more cautius while assigning points in future.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
A solution for Fortify Path Manipulation.
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question