?
Solved

User Authentication - and Struts :)

Posted on 2005-03-31
14
Medium Priority
?
524 Views
Last Modified: 2013-11-24
Hi,
   This is another one of my famous advice questions I'm afraid :)

   I'm putting an app together using Struts and Hibernate - so far that side of things is going swimmingly well. Now it's time to add basic authentication to it. When a user is not logged in, they are classed as a"guest" and can access some services but not many. If a user is signed in, they can access all the features of the site.

   What I'm looking for is opinions on the best way of handling authentication in this way. I haven't had to do it before and I figured it would be best to ask the experts on how they'd do it :)

   I look forward to hearing from everyone :)



PS The high points is because usually a lot of people reply - I try to dish them out fairly across the board but if you're really concerned about getting points, you might wanna sit this one out hehe :)
0
Comment
Question by:petepalmer
[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
  • 8
  • 6
14 Comments
 
LVL 35

Expert Comment

by:TimYates
ID: 13678783
I do it by storing usernames and encrypted passwords in a database table.  

Then, when the user logs in, encrypt their password, and compare it with the one in the database.

If login is successful, I add a flag to their session saying that they are logged in, and what level of user they are.

Then, I have an Tomcat Listener which listens to all HTTP requests, and a list of pages, and which types of users can access them.

This checks the page you are looking it, the rights you need and the rights you have (out of your session), and redirects you to a "Invalid page" page if your rights are not high enough.

I also have a jsp which builds the site menu/map dependant on your logged in status.

That's how I do it...  It could be neater I guess...but it kinda evolved over the space of a few months ;-)

Tim
0
 
LVL 1

Author Comment

by:petepalmer
ID: 13678905
I was thinking along the same lines but having a user object in the session which would have various methods for example isAdmin()

My menu page is just a basic jsp - I guess I should upgrade that :)


You said you encrypted the password - MD5 hash?
0
 
LVL 35

Accepted Solution

by:
TimYates earned 2000 total points
ID: 13678944
>> having a user object in the session which would have various methods for example isAdmin()

Actually, that's *exactly* what I've got too :-D

>> You said you encrypted the password - MD5 hash?

Yeah, MD5 hash, but I do a hash on

  username + "a fixed string of my own choosing" + password

so that users with the same password don't get the same hash :-)

It's not 100% secure (as there are MD5 collisions found), but it's better than plain text ;-)
0
Independent Software Vendors: 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 1

Author Comment

by:petepalmer
ID: 13678961
Sounds like a plan :)

Any pitfalls that I should look out for ?
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13678978
Dont forget the Listener will get called for all images/classes/everything  not just jsp's or *.do pages...

That's all I can think of for now :-/

Oh, and because you save the user in the session, if you upgrade a user to a better/worse level, they have to log out and back in again before any changes take effect...
0
 
LVL 1

Author Comment

by:petepalmer
ID: 13678991
Listener?  *innocent look*


I have a context listener so I know about those :)
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13679060
Something like this:

This only checks that the person is logged in, it has no concept of access levels...that can be an exercise for you ;-)

It will involve writing the code to replace the

          valid = CHECK TO SEE IF THIS USER CAN ACCESS THIS PAGE

bit... ;-)

hehehehehe

I hope this works, I have had to chop it about out of my code (to get rid of stuff you don't need)

Basically, save this as

org/webproject/filters/LoggedInFilter.java

compile it, and copy it to

WEB-INF/classes/org/webproject/filters

and add the following lines to WEB-INF/web.xml

  <filter>
    <filter-name>login</filter-name>
    <filter-class>org.picr.mvwa.filters.LoggedInFilter</filter-class>
  </filter>
...
  <filter-mapping>
    <filter-name>login</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

As you can see...when it fails, and sends you to "Welcome.do", it stores the URI you were trying to access in "RedirectOnLogin" in the session...

So when you log in, you can redirect the user to this URI, and they will go to where they were trying to get to ;-)

As I said, there is no "level based" access loggin in this...  basically, you succeed or fail, but hopefully this will give you a good base to start from, to add your level based access to :-)

Tim

-------------

package org.webproject.filters ;

import java.io.IOException ;
import java.util.StringTokenizer ;
import java.util.Vector ;
import javax.servlet.Filter ;
import javax.servlet.FilterChain ;
import javax.servlet.FilterConfig ;
import javax.servlet.ServletException ;
import javax.servlet.ServletRequest ;
import javax.servlet.ServletResponse ;
import javax.servlet.http.HttpServletRequest ;
import javax.servlet.http.HttpServletResponse ;
import javax.servlet.http.HttpSession ;

import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;

public class LoggedInFilter implements Filter
{
  private static Log log = LogFactory.getLog( LoggedInFilter.class ) ;

  private FilterConfig filterConfig;

  public void doFilter( final ServletRequest request,
                        final ServletResponse response, FilterChain chain ) throws
                        IOException, ServletException
  {
    HttpServletRequest req = (HttpServletRequest)request ;
    HttpServletResponse res = (HttpServletResponse)response ;
    HttpSession sess = req.getSession() ;

    boolean valid = true ;

    String uri = req.getRequestURI().substring( req.getContextPath().length() ) ;

    User user = null ;

    if( ( uri.length() < 2 ) ||
        ( uri.indexOf( "/images/" ) > -1 ) )
    {
      // do nothing...  valid is true, and we will show this page :-)
    }
    else if( sess == null )
    {
      valid = false ;
      sess = req.getSession( true ) ;
    }
    else
    {
      user = (User)sess.getAttribute( "User" ) ;
      valid = ( user != null ) ;
      if( valid )
      {
          valid = CHECK TO SEE IF THIS USER CAN ACCESS THIS PAGE
      }
    }
    if( !valid )
    {
        // Ok, the request is not valid, send them to the welcome page...
        log.info( "Denied access to " + uri ) ;
        String welcomePage = "/Welcome.do" ;
        String params = req.getQueryString() ;
        sess.setAttribute( "RedirectOnLogin", ( uri == null ? null : uri + ( params == null ? "" : "?" + params ) ) );
        res.sendRedirect( req.getContextPath() + welcomePage ) ;
    }
    else
    {
      if( uri.endsWith( ".do" ) ) // Stop people caching these pages...
      {
        // Set to expire far in the past.
        res.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT");

        // Set standard HTTP/1.1 no-cache headers.
        res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");

        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        res.addHeader("Cache-Control", "post-check=0, pre-check=0");

        // Set standard HTTP/1.0 no-cache header.
        res.setHeader("Pragma", "no-cache");
      }
      chain.doFilter( request, response ) ;
    }
  }

  public void setFilterConfig( final FilterConfig filterConfig )
  {
    this.filterConfig = filterConfig ;
  }

  public void init( FilterConfig config )
  {
    this.filterConfig = config ;
  }

  public void destroy()
  {
    this.filterConfig = null ;
  }
}
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13679065
You will need 2 levels of redirect.

1) If the user isn't logged in, where you store the URI they were trying to access, and send them to the login screen
2) if the user doesn't have the correct access rights, don't bother storing the URI, and send them to a "NO!" screen ;-)

Tim
0
 
LVL 1

Author Comment

by:petepalmer
ID: 13679079
oooh that's scary :)
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13679088
I'd try it with just some logging first, and slowly add in your checks (using that code as a template) :-)

That way you can see what's happening at every step :-)

You can do things like check that POST methods come from your site too, which stops people saving HTML forms, hacking them, and posting them from their machine ;-)

One step at a time is the best way though ;-)

Good luck!!

Tim
0
 
LVL 1

Author Comment

by:petepalmer
ID: 13679103
Fingers crossed ;)
0
 
LVL 1

Author Comment

by:petepalmer
ID: 13683200
is filterConfig a requirement ? :)
0
 
LVL 1

Author Comment

by:petepalmer
ID: 13683294
Guess not, got it working without using it hehe....

Now to figure out what else it does....
0
 
LVL 1

Author Comment

by:petepalmer
ID: 13683794
How do I get objects out of "application" context from my funky new filter? :)

0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
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:
Suggested Courses
Course of the Month10 days, 11 hours left to enroll

765 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