2

I'm new to Java EE. I created a login form and servlet to authenticate a user's credentials, but when I check the remote user with getRemoteUser() method after authentication, my code doesn't display the user name.

My login servlet is :

String uname,pass;
PreparedStatement ps=null;
uname=request.getParameter("uname");
pass=request.getParameter("pass");

ResultSet rs = null;
Connection con = null;
try {
    con = prepareConnection();

    String Query="select uname,email from passmanager where pass=?";
    ps=con.prepareStatement(Query);

    ps.setString(1,pass);
    rs=ps.executeQuery();

    while(rs.next())
    {
        if (uname.equals(rs.getString("uname")) || uname.equals(rs.getString("email"))) 
        {
            rs.close();                                                              
            ps.close();                                                            
            ps = null;                                                             
            con.close();                                                            
            con = null;  
            HttpSession session = request.getSession(true); 
            session.setAttribute("currentSessionUser",uname); 
            RequestDispatcher dis = request.getRequestDispatcher("/user.html");
            dis.forward(request, response);
            break;
        }
    }
}
catch(Exception e)
{
    System.out.println(e);
}

If anything need to change/modify in it please tell me and help me..... thanks in advance.

cheb1k4
  • 2,316
  • 7
  • 26
  • 39
James
  • 2,874
  • 4
  • 30
  • 55
  • The remote user will only be populated if you go through the container's way of authenticating users. If you implement it all by yourself, there's no way for the container to know that what you did was authenticating the user, and that the currentSessionUser session attribute contains the current user. See http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html for explanations and examples using Tomcat. – JB Nizet Feb 04 '13 at 12:38
  • have you tried `response.getheader?` or `response.getWriter` or `response.getoutputstream` ? – William Kinaan Feb 04 '13 at 12:41
  • What's the application server you want to deploy the servlet to? – Jacek Laskowski Feb 05 '13 at 13:19

3 Answers3

8

The HttpServletRequest#getRemoteUser() is part of container managed authentication which is basically just a simple <security-constraint> XML configuration entry in web.xml.

But you've there a completely homegrown servlet which does actually also do a pretty bad job of DB interaction (it's performing the comparison in Java instead of in SQL by a WHERE clause on both the username and password; further it also leaks JDBC resources away by not closing them in finally).

You've basically 2 options:

  1. Don't homegrow authentication. Delete all that bad, inefficient and resource-leaking code and use container managed authentication. You can find a kickoff example in this answer: Restrict JSP/Servlet access to specific users only

  2. Just get the logged-in user by session.getAttribute("currentSessionUser") and/or ${currentSessionUser} instead and homegrow a servlet filter for access restriction. You can find a kickoff example in this answer: Authenticating the username, password by using filters in Java (contacting with database)

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 2
    To be fair, he only loads the users with the same password. My main concern would be that passwords are stored in clear-text in the database. That will put the users at risk, rather than the health of the application. – JB Nizet Feb 04 '13 at 12:46
  • When we using j_security_check we must specify the **action="j_security_check"** this means that we need to create the servlet named j_security_check. Tell me am i right or not. – James Feb 04 '13 at 14:57
  • 1
    No. You don't need to create it yourself. It's already built into the container itself. All you need to create is a HTML login form which submits to predefined URL `j_security_check` with predefined parameters `j_username` and `j_password`. – BalusC Feb 04 '13 at 15:00
  • I'm storing username and password in my database. For j_security_check i think it needs to store the username and password in xml file. then how it able to validate the user information. – James Feb 04 '13 at 15:53
  • Just configure a database realm. See the link in answer for hints. – BalusC Feb 04 '13 at 15:54
  • I found that it is not possible to directly access the login page when using form based authentication. It is a special,redirect-able login page for secured resources. If the user needs to access the login page direcly, for that case how can i authenticate the user details.Please answer me for this [here](http://stackoverflow.com/questions/14708147/login-authentication-with-form-based-authentication-not-working) Thanks........... – James Feb 06 '13 at 11:55
  • James, please stop spamming my blog with offtopic/irrelevant comments requesting to look at a question of you here. Just ask the question the smart way and have patience until I see it. I do this all for free, so try to keep it kind and fun. – BalusC Feb 06 '13 at 12:05
2

To add to @BalusC's response, there's another approach to container managed authentication using the security methods from javax.servlet.http.HttpServletRequest in Java Servlet 3.0 (part of Java EE 6) – login, logout and authenticate. They're new methods in a HttpServletRequest object and they came almost unnoticed (why should it have been different if it'd taken so much time to get to this Java EE version with these simplifications?).

Regardless of the approach - programmatic or declarative one - you will eventually have to configure a user repository in your application server (that part is container-specific) and likely define a realm to point to the user repo in a deployment descriptor web.xml (as defaults might not suit your needs - BASIC, FORM or CLIENT_CERT).

In your case, the servlet does too much - the part that's responsible for retrieving users should be a part of a application server's custom user registry handler (or better yet - reuse what's already available in an application server - WebSphere V8.5 Liberty Profile or WebSphere V8.5) and once it's defined use <security-constraint> in web.xml or the above new security methods.

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
0

You are not logging your user doing this way. What you did was setting a session attribute who is named "currentSessionUser" and the container is not recognizing this as a "Authenticated user".

Search for "Realm configuration (your container's name)" to see how to do this configuration. Each container has its way to do this. :)

Diogo Moreira
  • 1,082
  • 2
  • 9
  • 24