October 2008 Entries

Recently, the CEO of Sprint could be seen in TV commercials stating "Technology is only great when you know how to use it.Here is an article that digs a little deeper into this ad campaign.  The purpose of the campaign is to highlight Sprint's customer service, which of course is vitally important to any company providing products or services. 

I am not here to criticize Sprint.  In fact, if you read the article, you will see that they are addressing technology simplicity as well as customer service.  I am here to criticize the statement above, specifically with software development in mind.

While customer service is vital, we cannot rely on it.  It doesn't matter how pleasant a customer service call is if the users are forced to call for support continually because they don't understand how the product works.  I'll paraphrase something I've heard or read before; "Technology is at it's best when you don't realize that it is there."  Now, that is a foundation to build a product on.

Good application designers are hard to find.  And even then, the design should be customized to the target user base.  So how do we make applications more intuitive to the user?  We listen.  We observe.  We ask the right questions. 

There are a lot of ways to accomplish this goal.  Paper prototyping (leading to usability testing) is one that has a lot to offer.  If you have never witnessed a usability session with paper prototypes, it might be difficult to truly understand the benefits.  In the usability session, your team sees firsthand how the user would interact with the application, before you have built it.  In a usability session, we listen, we observe, and we ask the right questions (frequently without vocalizing them).

How else do you simplify technology?  Well, by not doing the opposite.  I think, all too often, we developers tend to add something to an application because the technology is cool.  Sometimes the best answer is the simple one, not the one with that is most configurable.  TDD and YAGNI come to mind here.

I could sit here a long time with anecdotes about technology getting in the way.  The bottom line is, we should use a little bit of common sense.  If we had to go through hours of research or training to understand a new technology, is that something we want to expose a customer to?  The more we can keep technology hidden, the happier our customers will be.  This applies to framework builders as well.  How many times have we decided to use one framework over another because it is easier to use?

Strive for simplicity.

First of all, since my last post indicated I would be gone a while because of Huricane Ike, I guess it wouldn't hurt to provide an update.  Well, I still have a little bit of work to do on the house, but things are mostly back to normal for me.  There are still a lot of people in the Houston area recovering from the storm.  I've personally helped clean up two homes that had water 4-5 feet high on the first floor.  This makes me all the more glad that I am on the north side away from the storm surge.

Anyway, I thought I would just jump right back in the saddle with something that I've found lots of people asking about but only a few solutions.  All of the solutions I have found (including my own adapted solution) are specific to a particular ASP.Net configuration.

The problem: Redirect a user to an Unauthorized page when they attempt to navigate to a page they have no access to.  There are many nuances to this problem.  It really all depends on your ASP.Net configuration.  Are you using Windows authentication?  Forms Authentication?  Are you using membership and role providers?

My specific situation is an ASP.Net web site that uses both Membership and Role providers, in addition to Forms authentication.  The crux of the problem is that ASP.Net is too smart for it's own good.  When you set up Forms authentication in the web.config, one of the attributes includes the loginUrl.  This is used, firstly, for identifying the login page when the user is not yet authenticated.

When you throw authorization into the mix, the loginUrl is used yet again.  The FormsAuthenticationModule intercepts any 401 (not authorized) sent by the UrlAuthorizationModule and translates it into a 302 (redirect), redirecting to the login page.  I'm not quite sure why it was designed this way.  Clearly based on all of the posts on the net, there is a high demand for different behavior (that is, a separate "unauthorized" page).

The solution:  After playing with various solutions, I finally adapted a few of them into something I am comfortable with.  Granted, this is proprietary to ASP.Net's current behavior and may require changing in the future.  Hopefully, when a change is required, it will mean that Microsoft has provided a better solution (perhaps another web config attribute for the unauthorized page, or honoring the customErrors configuration).

Regardless, my solution involves intercepting the EndRequest event on the Application instance:

    1     void Application_EndRequest( object sender, EventArgs e )
    2     {
    3         if(User.Identity.IsAuthenticated && Response.StatusCode == 302 && Response.RedirectLocation.ToUpper().Contains( "LOGIN.ASPX" ))
    4         {
    5             if(!UrlAuthorizationModule.CheckUrlAccessForPrincipal( Request.FilePath, User, "GET" ))
    6             {
    7                 Response.RedirectLocation = "/Unauthorized.aspx";
    8             }
    9         }
   10     }

Basically, I check to see if the response is a redirect to the login page and if the user has already been authenticated.  Finally, I check to see if the user does not have access from the original requested page.  If all of those conditions are true, then I redirect them to the unauthorized page, instead of the login page.

Anyway, I hope this helps someone.  Now at least I won't have to search too long the next time I need it.

Happy coding