« Tomcat and SSL redirectionNothing to do with IT... »

29 comments

Comment from: Sameer [Visitor] Email
SameerHi Mathias,

Thanks for this well explained blog. I was wondering how tomcat would check the password without specifying any information about where to find the passwords in the LDAP drectory?

I tried using the above configuration, but I cannot get the user to get authenticated.
07/17/08 @ 17:32
Comment from: Thias [Member] Email
Hi Sameer,

Well, make sure that you've replaced the generic parameters in the <Realm /> definition by some that match your ldap server.
You're right about the password. I've been using Sun Directory as a LDAP server. I've never had to mention a specific field for the password...

Thanks for your comment. Do not hesitate to come back to me with more information ;-)
07/17/08 @ 21:46
Comment from: Robert Rowland [Visitor] Email
Robert RowlandIs there a way for the webapp to know what username was used to authenticate with? For example if you wanted to display somwhere on the webpage what user you are currently logged in as?
10/07/08 @ 17:54
Comment from: Thias [Member] Email
Hi Robert,

Once logged in, the user name can be fetch using the following:
<%= request.getRemoteUser() %>


I'm using this to display a "Welcome username" message on the tomcat app pages.

Hope this helps!
10/07/08 @ 18:21
Comment from: Ravindra [Visitor]
RavindraHi,

We are migrating our applicaton from Tomcat5 to tomcat-6.0.18. In our applicaton we are verifying users with LDAP. But when we tried to login we are getting following error:

HTTP Status 403 - Access to the requested resource has been denied.

Can someine please help us.

Thanks.
02/05/09 @ 11:59
Comment from: Raivndra [Visitor]
RaivndraJNDIRealm[Catalina]: lookupUser(ravindra.paliwal)
JNDIRealm[Catalina]: dn=uid=ravindra.paliwal,ou=Equant ,ou=People,o=globalone.net
JNDIRealm[Catalina]: validating credentials by binding as the user
JNDIRealm[Catalina]: binding as uid=ravindra.paliwal,ou=Equant ,ou=People,o=globalone.net
JNDIRealm[Catalina]: Exception performing authentication
javax.naming.ServiceUnavailableException: cod.dc.iad.equant.com:389; socket closed; remaining name ''
at com.sun.jndi.ldap.Connection.readReply(Connection.java:410)
at com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:340)
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:193)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2640)
at com.sun.jndi.ldap.LdapCtx.ensureOpen(LdapCtx.java:2549)
at com.sun.jndi.ldap.LdapCtx.ensureOpen(LdapCtx.java:2523)
at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1904)
at com.sun.jndi.ldap.LdapCtx.doSearchOnce(LdapCtx.java:1896)
at com.sun.jndi.ldap.LdapCtx.c_getAttributes(LdapCtx.java:1289)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_getAttributes(ComponentDirContext.java:213)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getAttributes(PartialCompositeDirContext.java:121)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getAttributes(PartialCompositeDirContext.java:109)
at javax.naming.directory.InitialDirContext.getAttributes(InitialDirContext.java:121)
at org.apache.catalina.realm.JNDIRealm.bindAsUser(JNDIRealm.java:1231)
at org.apache.catalina.realm.JNDIRealm.checkCredentials(JNDIRealm.java:1122)
at org.apache.catalina.realm.JNDIRealm.authenticate(JNDIRealm.java:868)
at org.apache.catalina.realm.JNDIRealm.authenticate(JNDIRealm.java:782)
at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:229)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:446)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:417)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:793)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:702)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:571)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:644)
at java.lang.Thread.run(Thread.java:534)

JNDIRealm[Catalina]: Closing directory context
02/06/09 @ 11:01
Comment from: marveen [Visitor]
marveentried with tomcat 5.5 and tomcat 6.0.18 on a server windows 2003 and it returns always an error when identificating
02/16/09 @ 15:14
Comment from: Thias [Member] Email
Hi Marveen,

What kind of error do you have?
Do you have any logs?

02/16/09 @ 22:01
Comment from: ambar [Visitor] Email
ambarI am on Tomcat 5.0.28 on Linux, and Sun Iplanet Directory Server 5.2. I have configured the realm according to this example, and also followed the tomcat docs supplied in the installation. I have made modifications to the web.xml file in webapps/jsp-examples/WEB-INF/. In the LDAP directory, I have created a group whose cn=tomcat and role1. What I see is: When I access the /security/protected page from the browser, I get HTTP Status 403 - Forbidden. Which means that the authentication succeeded (if I enter a wrong password, it says so), but the authorization failed. Please let me know where to look to resolve this issue.
02/26/09 @ 10:38
Comment from: Thias [Member] Email
Ambar,

You mean that you have to enter your login, and whatever login you enter, you just get the Forbidden status page?
Did I miss something?
Otherwise, make sure that you have access to the index.jsp page...
02/26/09 @ 12:17
Comment from: timo [Visitor]
timoHi,

Try adding

allRolesMode="authOnly"

inside the realm-tag.

-timo-

03/12/09 @ 08:42
Comment from: ev [Visitor]
evthanks timo...you made my day.
allRolesMode="authOnly" fixed all my problems
04/24/09 @ 07:05
Comment from: Melvin Thompson [Visitor]
Melvin ThompsonI'm new to Java; I have a question that may sound stupid. Where exactly is the coding for "j_security_check" that's displayed in the "action" of the form tag.
06/22/09 @ 16:05
Comment from: Java User [Visitor]
Java UserHi,Mathias,
thanks for providing such a great tutorial. I followed your tutorial, and getting work some how. After authenticating is success then how to redirect to the success page? And in success page I want to display the user name and his roles from LDAP. So can you suggest me the code snippet to get the roles of an authenticated user and redirecting to the sucess page.
09/18/09 @ 11:30
Comment from: Thias [Member] Email
Hi "Java User",

First, thank you for your kind comment...
Well, let try to get a little more technical now...
It's been a long time since I've done this tomcat thing, but as far as I remember, the success page is simply the index.jsp page from your webapp:
$CATALINA_HOME/webapps/yourapplication/index.jsp


In order to display the user name, you can use the following in your index.jsp page:
<%= request.getRemoteUser() %>



I'm not sure there are other built-in functions you can use to access LDAP information about the logged in user. I guess that you have to implement an LDAP request to get whatever LDAP field you want and display it in your webapp, once you have the user name...

Hope this helps...
09/22/09 @ 05:43
Comment from: suresh [Member] Email
sureshHi, I am trying to do LDAP Authentication from Tomcat.When I am accessing the web page am getting pop-up for username and password and after pressed the OK button. Tomcat console displaying following error message. Error Details : SEVERE: Exception performing authentication javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C09 062B, comment: In order to perform this operation a successful bind must be comp leted on the connection., data 0, vece ]; remaining name 'TestUser@SoftphoneAD.c om' at com.sun.jndi.ldap.LdapCtx.mapErrorCode(Unknown Source) at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source) at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source) at com.sun.jndi.ldap.LdapCtx.c_getAttributes(Unknown Source) at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_getAttributes(Unknown Source) at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getAttributes(Unk nown Source) at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getAttributes(Unk nown Source) at javax.naming.directory.InitialDirContext.getAttributes(Unknown Source ) at org.apache.catalina.realm.JNDIRealm.getUserByPattern(JNDIRealm.java:1 009) at org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:973) at org.apache.catalina.realm.JNDIRealm.authenticate(JNDIRealm.java:899) at org.apache.catalina.realm.JNDIRealm.authenticate(JNDIRealm.java:810) at org.apache.catalina.authenticator.BasicAuthenticator.authenticate(Bas icAuthenticator.java:181) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authentica torBase.java:491) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j ava:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j ava:117) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal ve.java:108) at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.ja va:393) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav a:151) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java :874) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.p rocessConnection(Http11BaseProtocol.java:665) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpo int.java:528) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFol lowerWorkerThread.java:81) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP ool.java:689) at java.lang.Thread.run(Unknown Source) Dec 22, 2009 4:33:28 PM org.apache.catalina.realm.JNDIRealm authenticate Please tell me where I made the mistakes. Thanks and Regards, SureshKumar K
12/22/09 @ 13:22
Comment from: Stephen [Visitor]
StephenHi there. I know it's been a long time since you wrote this article, but I'm hoping you're still around. I've been trying to get my Tomcat and LDAP server to talk for a few days now, but just keep running into problems. Your tutorial is the first I've found that is actually good , so thanks for that to start!

I've managed to get the index.jsp page to show, and I believe it is hitting the LDAP server okay - if you use an invalid password it spits you to error.jsp like it should - but when you hit "okay" with a valid password it gives a 403 error. Do you have any idea what might be the cause for this? As far as I know I simply followed your instructions to the letter.

I can post my web.xml, server.xml, etc if needs be. I hope you are still around, and I hope you can help me!
06/16/10 @ 15:45
Comment from: siva [Visitor]
sivaHi, I am also facing the same issue right now. I've been trying to get my Tomcat and LDAP server to talk for a few days now, but just keep running into problems. Please try to help it out to start! I've managed to get the index.jsp page to show, and I believe it is hitting the LDAP server okay - if you use an invalid password it spits you to error.jsp like it should - but when you hit "okay" with a valid password it gives a 403 error. Do you have any idea what might be the cause for this? As far as I know I simply followed your instructions to the letter. I hope you are still around, and can help me!
08/05/10 @ 12:10
Comment from: Newie [Visitor]
NewieHello, nice tutorial. In order to understand LDAP, It would be great if you could highlight in bold the generic parameters in the "Realm" definition that need to be matched from the real ldap server.
Thank you.
Newie
08/27/10 @ 13:58
Comment from: David [Visitor]
DavidHallo again,
Do I need to change the pairs ou=people, dc=domain, uid=(0) to the equivalentes in my LDAP server. I mean both sides (Strings) of the comparison? Or maybe just the right side value of the comparison? Are the keywords uid, ou, dc, cn, memberUid standard keywords for all posible configurations? And by configurations also mean not only in Tomcat, but also Spring Security, etc. I know this is an exhaustive question, I am having problems finding documntation. Thank you for the tutorial.
08/27/10 @ 15:23
Comment from: Thias [Member] Email
@David,

The entry userPattern="uid={0},ou=people,dc=domain,dc=com" should match your LDAP server.
In my case, users are stored in LDAP (I'm running Sun Directory Server here - but I could have been OpenLDAP or any other one) following this schema:
The user name is known by the uid.
Users entries are stored in the "people" ou, for the "domain.com" domain.

uid, ou, dc, cn, ... are quite standard, but the LDAP schema may vary depending on the LDAP server you're using...

Well, that's a really short answer to your long question, but anyone who wants to add more is welcome! ;-)
08/27/10 @ 16:04
Comment from: James [Visitor]
JamesHallo,
what do uid={0} and memberUid={1} mean? I a mean the numbers between curly brackets. Great tutorial.
James
08/29/10 @ 03:17
Comment from: David [Visitor]
DavidHello,

Thankyou for the article and the help comments. I have got the following info from an apache server. I have change the domain, group and company names. I do not know how to map this info to the tomcat configuration.
AuthLdapUrl ldap://ldap02.domain.com:389/o=company,c=com?uid?sub?(objectClass=*)

Require ldap-group cn=thegroup,o=company,c=com
08/29/10 @ 17:36
Comment from: Prad [Visitor]
Pradhi, where we arfe definining j_security_check ? is it predefined ?
02/03/11 @ 13:47
Comment from: Jon [Visitor]
JonWhat do you do in the case you're using roleOccupant from organizationalRole class instead of memberUid?

roleSearch="roleOccupant={1}"

Does that work? because the roleOccupant is a DN and not a UID so I don't think it works.
03/30/11 @ 20:21
Comment from: Pushkar [Visitor] Email
PushkarThanks. After banging my head, I finally got it working.

For folks who are asking about j_security_check, in my case it points nowhere. The idea is that when a restricted resource is requested, tomcat will redirect to the login page. On successful login, the page is redirected to restricted page which was originally requested. On failed login, it redirects to error.jsp.

My requirement is plain - authenticate all users regardless of their group. So I got rid of the roles. Finally my web.xml looks like this


<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.sample.jnditry1.hello</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/restricted/hello</url-pattern>
</servlet-mapping>

<security-constraint>

<display-name>Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<!-- Define the context-relative URL(s) to be protected -->
<url-pattern>/restricted/*</url-pattern>
<!-- If you list http methods, only those methods are protected -->
</web-resource-collection>

<auth-constraint>
<!-- Anyone with one of the listed roles may access this area -->
<role-name>*</role-name>
</auth-constraint>
</security-constraint>


As for the servlet hello -

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub

resp.getWriter().write("GET username=" + req.getUserPrincipal().getName());
}


Finally my request is HTTP GET - http://localhost:8080/jnditry1/restricted/hello

which asks for login and once I do shows my username. Hope that helps.
08/26/11 @ 11:01
Comment from: Filipe Vieira [Visitor] Email
Filipe VieiraHi,

I've found this article very useful for my project, I just have one question.

Is it possible to select x users from a single role to gain access?

For example, my AD have a role named "users" with the user "u1","u2" and "u3".


And after i define the role name:

<role-name>users</role-name>

I just want u1 and u3 to gain access.

Thanks!
11/28/11 @ 15:27
Comment from: Dave Godbey [Visitor] Email
Dave GodbeyGreat stuff. I have this working fine. Now downstream I want to use site minder to sso auto login.

How can I tell tomcat to populate http headers with info from the ldap record, eg. first name, last name, user name.

The authorization header is there, but what I really want is a header with the remote user in it, eg. the username I logged in with.
02/10/12 @ 19:10
Comment from: Mika [Visitor]
MikaHi Mathias,

Thank you for this very good example.

- Mika
09/18/12 @ 12:35