Friday, December 31, 2010

GWT Designer

I am not a fan of WYSIWYG software.  Almost every experience I had with WYSIWYG tools had the same pattern:
  1. I implement some application using the tool because I am pressed for time.
  2. I get the initial project done very quickly.
  3. Someone requests a change.
  4. Because of the WYSIWYG generated code, I essentially have to rewrite the app.
Maybe I just didn't use the WYSIWYG right.  Obviously, a lot of people love them.  But they were always counter-productive for me.  In the end, they cost me more time than they saved.  So, you can imagine my feelings when I read about GWT Designer.  Here was a Drag and drop visual editor for GWT, complete with integration for SmartGWT and Ext GWT.  I was hesitant, to say the least.

But I also firmly believe that as a Software Engineer, you have to keep your mind open and constantly re-evaluate new tools.  So, I installed the GWT Designer plugin for Eclipse.  I used it for my capstone project, a CRUD application for running a sign installation company.  I was pleasantly surprised.  

Here are a few observations about the Editor:
  1. I was able to jump between code and the visual editor easily
  2. Changing my code by hand didn't break the visual editor 
  3. The code generated by the editor was easily readable and clean
Even though I started with the WYSIWYG, as I got a simple layout produced, I found myself easily translating into the code. It was a good experience.  The visual components I created were originally going to be mock ups, but they were so clean, I've transitioned them into the working code.  The application is not done yet, but its looking good - I've already been able to easily incorporate changes requested by my client.  

Now, here are the drawbacks I encountered:
  1. My 5 year old PC and laptop run the visual components a little slow. 
  2. The visual rendering isn't yet perfect.  While it was mostly reflective of the actual output, there were a few differences.
All in all, though, the drawbacks were more annoyances than restrictions.

If you use GWT, I recommend you try GWT Designer.

Friday, December 24, 2010

GWT Simple Security Configuration

For my capstone project in my MSE program at Carroll University, I am writing a GWT application. One of the requirements for this application is security. There are several posts on securing a GWT application on the Web already, but most of them are more heavy weight solutions that show you how to use Spring-AOP and Spring-security to secure your app.

For this project, I don't need anything that heavy-weight. Here is a little review of how I secured this application.

First, I wanted each service to have it's own access controls. More specifically, I want to be able to secure each method in each service. Second, I want to be able to support Role-based access. This way I can add users to roles to grant them the permissions they need. Finally, I don't have a real need to redefine role access in real-time. Given these constraints, I was able to put together a quick and easy solution to secure my application.

First, I decided that I wanted to be able to easily see in my code what the access control was. It seemed to me that Annotations would be an easy way to do this. Something like:

@Secure("ROLE_ADMINISTRATOR")

But I want to be able to specify multiple roles that can be configured to this action, so, multiple roles would look more like this:

@Secure({"ROLE_ADMINISTRATOR, ROLE_CONFIGURATION_MANAGER"})

So, the first thing I did was define the Annotation.


package com.archie.sma.server.util.security;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Secure {
  public String[] value();
}
  
AS you can see, annotations are annotated. This one says that this annotation applies to Methods, and it is kept at runtime.

Next I needed to apply the annotation to my services. This was quite easy. In my Service interface on the client, I used the annotation:

@Secure({"ROLE_ADMINISTRATOR", "ROLE_CONFIGURATION_MANAGER"})
public Object get(String id) throws Exception {
//Method implementation here...
}

Of course, I now need to tie these two together. Since I'm Using GWT, I decided to Extend the GWTServerServlet. By extending the servlet and over-riding the processCall and onAfterRequestDeserialized method, I am able to easily use a little bit of Reflection to get the annotation and determine if the user in Session has access to the method. This approach also requires me to extend my new security Servlet for all my secured classes. So its on the developer to ensure he is extending the class correctly. Here is the class:





public class SecureRemoteServiceServlet extends RemoteServiceServlet {

  private transient IDaoFactory daoFactory;

  @Override

  public void init(ServletConfig configthrows ServletException {

    super.init(config);

    daoFactory = new DaoFactory();

  }

  /**

   

   */

  private static final long serialVersionUID = 1000L;

  private static final String USER = "USER";

  private User user;

  @Override

  protected final void onAfterRequestDeserialized(RPCRequest rpcRequest) {

    Method method = rpcRequest.getMethod();

    Secure secure = method.getAnnotation(Secure.class);

    Boolean hasAccess = Boolean.FALSE;

    if (secure != null) {

      

      String[] roles = secure.value();

      HttpServletRequest request = getThreadLocalRequest();

      user = (Userrequest.getSession().getAttribute(USER);

      if (user != null) {

        List<Role> userRoles = user.getRoles();

        for (Role role : userRoles) {

          for (int i = 0; i < roles.length; i++) {

            if (role.toString().equals(roles[i])) {

              if(hasAccess != null) {

                hasAccess = Boolean.TRUE;

              }

            }

          }

        }

      }

    }

    if (!hasAccess){

      throw new RuntimeException("Not Authorized");

    }

  }

  /*

   * @Override public final String processCall(String payload) throws

   * SerializationException { if (!hasAccess) { throw new

   * UnexpectedException("Security Exception", new Exception(

   * "Not Authorized")); } return super.processCall(payload); }

   */



  public User getUser() {

    return user;

  }



  public void setUser(User user) {

    this.user = user;

  }



  public IDaoFactory getDaoFactory() {

    return daoFactory;

  }



  public void setDaoFactory(IDaoFactory daoFactory) {

    this.daoFactory = daoFactory;

  }

}


So that is my quick and dirty security implementation for my GWT app. This is not what you would call an enterprise solution, but it is a quick way to implement security for a little, self-contained application.