Java
  Home arrow Java arrow Page 5 - Securing Struts Applications
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
JAVA

Securing Struts Applications
By: McGraw-Hill/Osborne
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 94
    2005-09-15

    Table of Contents:
  • Securing Struts Applications
  • Using Container-Managed Security
  • BASIC Login
  • FORM-Based Login
  • Application-Managed Security
  • Page/Action-Level Security Checks
  • Using Cookies
  • SSLEXT to the Rescue

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Securing Struts Applications - Application-Managed Security


    (Page 5 of 8 )

    If container-managed security is not sufficient for your application, then you need consider creating your own security structure. Generally, you need to address the same issues in application-managed security that are addressed in container-managed security:

    • How and when do you authenticate the users?
    • What determines the authorization levels?
    • Is there a guest user and, if so, what privileges does that user have?
    • Does the application need to support HTTPS for transmission of sensitive data?

    The following sections look at several ways of handling these issues. As you read through them, you will apply your knowledge to the Mini HR application. Most of this discussion applies to Java-based Web applications in general—not just Struts-based applications.

    Creating a Security Service

    Using application-managed security requires different skills and knowledge than are required to use a container-managed approach. For application-managed security, you need to rely on traditional “best practices” development. For use with Mini HR, you will create a SecurityService interface API that will act as a façade for whatever underlying implementations exist. The definition of the interface to meet the needs of the Mini HR application is shown here:

    package com.jamesholmes.minihr.security;
    public interface SecurityService {
      public User authenticate(String username, String password)
        throws AuthenticationException;
    }

    Next is a sample implementation that uses a HashMapto store the user data in memory. Of course, a real implementation would retrieve this data from a persistent store such as a file system, relational database, or LDAP server.

    package com.jamesholmes.minihr.security;
    import java.util.HashMap;
    import java.util.Map;
    public class SecurityServiceImpl implements SecurityService {
      private Map users;
      private static final String ADMIN_ROLE = "administrator";
     
    public SecurityServiceImpl() {
        users = new HashMap();
        users.put("bsiggelkow",
         
    new User( "bsiggelkow","Bill", "Siggelkow", "thatsme",
            new String[] {ADMIN_ROLE}));
        users.put("jholmes",
          new User( "jholmes","James", "Holmes", "maindude", 
            new String[] {ADMIN_ROLE}));
        users.put("gburdell",
          new User( "gburdell","George", "Burdell", "gotech",
            new String[] {ADMIN_ROLE}));
      }
     
    public User authenticate(String username, String password)
        throws AuthenticationException
      {
        User user = (User) users.get(username);
        if (user == null)
         
    throw new AuthenticationException("Unknown user");
        boolean passwordIsValid = user.passwordMatch(password);
        if (!passwordIsValid)
         
    throw new AuthenticationException("Invalid password");
        return user;
      }
    }

    This interface provides the basic security services. The authenticate( )method verifies the user’s password and returns an object that represents the user. For the authorization needs of the application, there are different alternatives. While it may be tempting to engineer a complete role-based infrastructure, a more pragmatic approach is to provide a mechanism to determine if a user is an administrator. Following is the object that will hold the user data:

    package com.jamesholmes.minihr.security; 
    import java.io.Serializable;
    public class User implements Serializable {
      private String firstName;
      private String lastName;
      private String username;
      private String password;
      private String[] roles;
     
    public User(String name, String fName, String lName,
        String pwd, String[] assignedRoles) {
        username = name;
        firstName = fName;
        lastName = lName;
        password = pwd
        roles = assignedRoles;
     
    }
     
    public String getUsername() {
        return username;
      }
     
    public String getFirstName() {
        return firstName;
      }
     
    public String getLastName() {
        return lastName;
      }
     
    public boolean passwordMatch(String pwd) {
        return password.equals(pwd);
     
    }
     
    public boolean hasRole(String role) {
        if (roles.length > 0) {
          for (int i=0; i<roles.length; i++) {
            if (role.equals(roles[i])) return true;
         
    }
        }
        return false;
     
    }
     
    public boolean isAdministrator() {
        return hasRole("administrator");
      }
    }

    Notice that some basic information that can be used for personalization, such as the user's first and last name, has been included. In addition, the isAdministrator( ) method indicates whether or not the user is an administrator. Also a hasRoll( ) method has been implemented that will indicate whether or not a user has been assigned a given role. This method will be useful with customized Struts role processing. To tie this custom security service into the application, you also need to create a LoginAction that will process the user login, as shown in the following code. A LogoutAction that allows a user to log out of the application is also created by the following code. A logout action typically needs to just invalidate the user’s session. While you cannot force a user to log out, it is important to provide this feature, particularly if your application is accessible from a public terminal.

    package com.jamesholmes.minihr; 
    import javax.servlet.http.*;
    import org.apache.commons.beanutils.PropertyUtils;
    import org.apache.struts.action.*;
    import com.jamesholmes.minihr.security.*;
    public final class LoginAction extends Action {
     
    public ActionForward execute(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception
     
    {
        HttpSession session = request.getSession();
        String username =
        
    (String) PropertyUtils.getSimpleProperty(form, "username");
        String password =
         (String) PropertyUtils.getSimpleProperty(form,"password");
       
    SecurityService service = new SecurityServiceImpl();
        User user = service.authenticate(username, password);
        session.setAttribute("User", user);
        // Forward control to this Action's success forward
        return mapping.findForward("success");
     
    }
    }

    First, the action gets the username and password from the login form. Then, it calls the authenticate method of the security service. The returned user is then stored in the session. The exception handling is performed using Struts’ declarative exception handling. Back at the index page, you need to change it from the container-managed implementation as shown in the following example. In this case, you want to check the administrator bean property of the user and display the link only if the value is true. Note also that you must explicitly check whether the User object is in the session. This handles the case where the user has not yet been authenticated.

    <%@ taglib uri="/WEB-INF/tlds/struts-html.tld" prefix="html" %>
    <%@ taglib uri="/WEB-INF/tlds/struts-logic.tld" prefix="logic" %>
     
    <html>
    <head>
     
    <title>ABC, Inc. Human Resources Portal</title>
    </head>
    <body>
    <font size="+1">ABC, Inc. Human Resources Portal</font><br>
    <logic:notPresent name="user" scope="session">
    <hr width="100%" noshade="true">
    <html:form action="/login">
    Username: <html:text property="username"/><br/>
    Password: <html:password property="password"/><br/>
    <html:submit value="Login"/>
    </html:form>
    <html:errors/>
    </logic:notPresent>
    <hr width="100%" noshade="true">
    <ul>
    <logic:present name="user" scope="session">
    <logic:equal name="user" property="administrator" value="true">
    <li><html:link forward="add">Add an Employee</html:link><li>
    </logic:equal>
    </logic:present>
    <li><html:link forward="search">Search for Employees</html:link></li>
    </ul>
    </body>
    </html>

    The important modification to this index page is the use of the <logic:present> tag to hide or show the login form. In addition, the <logic:equal> tag is used to hide or show the Add an Employee link. You are not finished, however. First, remove (or comment out) the container-managed security sections from the web.xml file. Then, remove the roles attribute from the add.do action mapping.

    You are not done yet, however. Notice that there is now nothing to prevent someone who is not an administrator from adding a new employee. Anyone can browse directly to the Add an Employee page and submit the form. In addition, although securing the add.jsp page is not critical, it is imperative that you secure the AddAction (add.do). What you need to do is implement the checks that were in place with container-managed security. There are several alternatives to consider.

    More Java Articles
    More By McGraw-Hill/Osborne


       · Very good article. Concepts are explained in very detail.
       · i found this article very helpful ...........what should i write in the User class...
       · The concepts described in the article all act on the assumption to declare the...
     

    Buy this book now. This article is excerpted from chapter 19 of the book The Complete Reference: Struts, written by James Holmes (McGraw-Hill/Osborne, 2004; ISBN: 0072231319 ). Check it out at your favorite bookstore. Buy this book now.

    JAVA ARTICLES

    - Deploying Multiple Java Applets as One
    - Deploying Java Applets
    - Understanding Deployment Frameworks
    - Database Programming in Java Using JDBC
    - Extension Interfaces and SAX
    - Entities, Handlers and SAX
    - Advanced SAX
    - Conversions and Java Print Streams
    - Formatters and Java Print Streams
    - Java Print Streams
    - Wildcards, Arrays, and Generics in Java
    - Wildcards and Generic Methods in Java
    - Finishing the Project: Java Web Development ...
    - Generics and Limitations in Java
    - Getting Started with Java Web Development in...







    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 2 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek