Java Weblog: Login

[article] [edit page] [discussion] [history]

From Humanitarian-FOSS Project Development Site

Welcome! You've decided to learn how to make a more secure weblog. Follow the steps below:

Contents

Login

Time for the login functionality. First you will need to add a new field in your blog_pass table in the database for usernames, and then subsequently in your comments and thread tables. Go into phpMyAdmin, and to your blog database. Here is the MySQL code: mysql> ALTER TABLE `blog_pass` ADD `user_name` VARCHAR( 255 ) NOT NULL ; mysql> ALTER TABLE `comments` ADD `user_id` VARCHAR( 255 ) NOT NULL AFTER ; mysql> ALTER TABLE `thread` ADD `user_id` VARCHAR ( 255 ) NOT NULL AFTER ;

You can always do this using the GUI, too. Just go into the table, click on the Structure tab, and go down to where it says "Add [1] field(s)" and just add it to the end of the table and click "Go." The next screen will allow you to name the field, give it the length/values, and other attributes. Then click "Save," as "Go" will just allow you to add another field, but won't add the first one until you click on "Save." As long as you are referencing the table fields by name and not by number, it really doesn't matter where the new fields go.

Then, yet another .jsp file

login.jsp

Here it is:

<html><head><title>Web log Entry</title></head><body bgcolor="white">

<form action="/blog/Login"> Log Entry:
<%

       String username = request.getParameter("username");

String password = request.getParameter("password"); %>

Username: <input type = "text" name = "username" value = "" size = "30">
Password: <input type="text" name="password" value="" size="30">
<input type="submit" value="Login"> </form>

</body></html>

Credentials.java

This class checks the users credentials at every page they visit, making sure that they are still logged in correctly.

package jblog;

import java.io.*; import java.text.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import java.sql.*; import java.net.URLEncoder;

/**

* checks credentials of user attempting to login
*
* @Myles Garvey
*/

public class Credentials { public static final int NO_USERNAME = 0;

   	public static final int BAD_PASSWORD = 1;
   	public static final int USER_INFO_PASS = 2;

public static int checkCredentials(String userName, String password)

   	{
       	try
       	{
          	// create a new MySQLConnector object

MySQLConnector mydb = new MySQLConnector();

       	// get a valid Statement object from the connector
          	Statement stmt = mydb.connect();


           	ResultSet rs = stmt.executeQuery("select password,user_name from blog_pass where
user_name =\"" + userName + "\"");

//grab the user name and password information if(rs.next()) {

       		    String userNameDB = rs.getString(2);

String passwordDB = rs.getString(1); mydb.disconnect(stmt); if(!(userNameDB.equalsIgnoreCase(userName))) return NO_USERNAME; else if(!(passwordDB.compareTo(password) == 0))

               		return BAD_PASSWORD;

else

               		return USER_INFO_PASS;

}

       	  else
               	return NO_USERNAME;
        	}
       	catch (Exception ex)

{

       	}

return NO_USERNAME;

   	}

}

Login.java

This class handles the login action of the weblog. If a user tries to access the blog using just http://localhost:8080/blog/Show, they will automatically be redirected to the login page.

package jblog;

import java.io.*; import java.text.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import java.sql.*; import java.net.URLEncoder;


public class Login extends HttpServlet {

   private MySQLConnector mydb = null;
   private PrintWriter out = null;
   
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
   {
       out = response.getWriter();
       String un = request.getParameter("username");

String pw = request.getParameter("password");

int status = Credentials.checkCredentials(un,pw);

switch(status) { case Credentials.NO_USERNAME:

out.println("

Wrong Username Inputted, please <a href = \"/blog/login.jsp\">try again</a>

");

break; case Credentials.BAD_PASSWORD:

out.println("

Wrong Password for " + un + " please input the right password and <a href =\"/blog/login.jsp?username="+URLEncoder.encode(un) + "\">try again</a>

");

break; case Credentials.USER_INFO_PASS: HttpSession ses = request.getSession(); ses.setAttribute("username",un); ses.setAttribute("password",pw); ses.setAttribute("loggedin","true"); response.sendRedirect("/blog/Show"); break; }

   }
   public void doPost(HttpServletRequest request,
                      HttpServletResponse response)
       throws IOException, ServletException
   {
       // doPost just calls goGet 
       doGet(request,response);
   }

}

Logout.java

This class handles the logout action of the weblog, and closes the user's session.

package jblog;

import java.io.*; import java.text.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import java.sql.*; import java.net.URLEncoder;


public class Logout extends HttpServlet {

     private PrintWriter out = null;
   
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
   {

HttpSession ses = request.getSession(); ses.removeAttribute("username"); ses.removeAttribute("password"); ses.removeAttribute("loggedin"); response.sendRedirect("/blog/login.jsp");

   }
   public void doPost(HttpServletRequest request,
                      HttpServletResponse response)
       throws IOException, ServletException
   {
       // doPost just calls goGet 
       doGet(request,response);
   }

}

web.xml

Time to add in those servlets! Add in Login and Logout.

Editing the Rest of Your Classes

The login system works using sessions that each user has until he or she logs out. At every page they visit on the weblog, the application must check their credentials and, based on the outcome, allow or disallow them from viewing that page. This requires a lot of changes in your other classes so that they do this credential check.

Show.java

In the doGet method, add the following code, right at the beginning, before the response.setContentType("text/html");

        out = response.getWriter();

add the following:

//Check credentials to see if user is logged in and if not then check the login. HttpSession ses = request.getSession(false); if(ses==null) { response.sendRedirect("/blog/login.jsp"); return; } else { String log = (String)ses.getAttribute("loggedin"); if(log==null) { response.sendRedirect("/blog/login.jsp"); return; } String un = (String)ses.getAttribute("username");

       	String pw = (String)ses.getAttribute("password");

int check = Credentials.checkCredentials(un,pw);

if(!(check == Credentials.USER_INFO_PASS)) { response.sendRedirect("/blog/login.jsp"); return; } }

Then, to add some personality to the weblog, add this into the HTML header after displaying "My Web log":

out.println("

Welcome, " + (String)ses.getAttribute("username") + "!

");

which will display "Welcome, username".

Next, change // get the parameters "data" and "password"

       // from the local environment (if they exist)
       String data = request.getParameter("data");
       String password = request.getParameter("password");
       if ( (data != null) && (password != null) )
       {
           // the user has submitted an entry. call the writeData method 
           writeData(data,password);
       }
       else
       {
           // the user submitted either data or password, but not both   
           out.println("Missing data or password, please <a href=\"add_data.jsp\"> try again</a>.");
       }
       out.println("</body>");
       out.println("</html>");
   }

to:

// get the parameters "data" and "password"

       // from the local environment (if they exist)
       String data = request.getParameter("data");
       writeData(data);
       
       out.println("</body>");
       out.println("</html>");
   }

Then, change your entire writeData() method to the following:

  // writeData writes the log entry to the db table 
   private void writeData(String data)
   {
       try
       {
          // create a new MySQLConnector object 
          mydb = new MySQLConnector();
          // get a valid Statement object from the connector 
          Statement stmt = mydb.connect();

int written = stmt.executeUpdate("insert into blog (data) values (\"" + data + "\")");

          out.println("Your entry was recorded. 


<a href=\"/blog/Show\"<View Entries</a>"); // disconnect from MySQL mydb.disconnect(stmt); } catch (Exception ex) { out.println("Whoops, your entry was not recorded!

" + ex.toString() ); } }

Next, we want to add in a link to be able to logout-again, without having to do it manually. So, add in this line before after calling printEntries: out.println("<a href = \"/blog/Logout\">Log Out</a>");

ShowComment.java

This is less complicated than the Show class. In the doGet method, add the same credentialing code, and that's it.

Write.java

Again, add the credentialing code, and after the HTML header, change // get the parameters "data" and "password"

       // from the local environment (if they exist)
       String data = request.getParameter("data");
       String password = request.getParameter("password");
       if ( (data != null) && (password != null) )
       {
           // the user has submitted an entry. call the writeData method 
           writeData(data,password);
       }
       else
       {
           // the user submitted either data or password, but not both   
           out.println("Missing data or password, please <a href=\"add_data.jsp\"> try again</a>.");
       }
       out.println("</body>");
       out.println("</html>");
   }

to:

// get the parameters "data" and "password"

       // from the local environment (if they exist)
       String data = request.getParameter("data");
       writeData(data);
       
       out.println("</body>");
       out.println("</html>");
   }

WriteComment.java

Add the same credentialing code, again, in the same place.

And, similarly to Write, change this:

// get the parameters "data" and "password"

       // from the local environment (if they exist)
       String data = request.getParameter("data");
       String password = request.getParameter("password");

String blogid = request.getParameter("blogid");

       if ( (data != null) && (password != null) )
       {
           // the user has submitted an entry. call the writeData method 
           writeData(data,password,blogid);
       }
       else
       {
           // the user submitted either data or password, but not both   
           out.println("Missing data or password, please <a href=\"add_data.jsp\"> try again</a>.");
       }
       out.println("</body>");
       out.println("</html>");
   }

to this: // get the parameters "data" and "password"

       // from the local environment (if they exist)
       String data = request.getParameter("data");
       

String blogid = request.getParameter("blogid");

       writeData(data,blogid);
       
       out.println("</body>");
       out.println("</html>");
   }

The parameters of the writeData() method need to be changed to eliminate the String password part. In addition, we can take out the "trivial security", since we now have better security. So, delete everything from the comment //first some really trivial security all the way to the end of the following if/else statement. You still need the // disconnect from MySQL lines, so don't delete those.

Don't forget to compile your java classes, and reload the JBlog session in the Tomcat Manager. Then check out your new weblog!

More to come as we add more!

Personal tools