Matt RaibleMatt Raible is a Web Developer and Java Champion. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

Simple Intentions turn into Remember Me Login

I woke up this morning, and had the simple intention of blogging about one of my favorite tools, The Color Schemer. If you're a wanna-be designer like me, it's awesome. It helps you match "like" colors and also allows you to select any color on your screen. It's one of my most invaluable web design tools. Putting a tip about this was my only hope at 4:30 when I sat down at this computer. Now it's 5:39.

Why am I still here? I got caught up in reading the Colorado Bloggers mailing list - which actually got some traffic yesterday. This is one of the first times I've received a message from the list. One of the members pointed me to a another Photo Album for the web. It's called Gallery and she has an example setup. Looks like it runs on PHP. Well that shouldn't have taken me an hour, right?

The activity that's filled my last hour has been wrestling with Erik Hatcher's request for "remember me" functionality in a J2EE app, using container-managed security. The good news is that I did get it working - here's how:

  1. First, I added a checkbox called "rememberMe" to my login.jsp. When the user clicks "submit", I do some JavaScript logic. This logic entails saving the username and password as cookies - but only if the rememberMe checkbox is checked. If rememberMe is checked, a cookie is set called "rememberMe" with a value of "true."
  2. Using Roller's BreadCrumbFiler (maps to /*), I added some logic to check for the existence of the "rememberMe" cookie, and if it exists, to route the user to "j_security_check?j_username="+usernameCookie+"&j_password="+passwordCookie.

This all worked fine and dandy right off the bat - took me about 10 minutes to implement. The problem was that a user couldn't "logout." So I've spent the last hour (now it's been an hour and 1/2) with my own ignorance trying to delete cookies (and doing null checks and such) so users could logout. And I just got it working - fricken sweet! What a way to start the day! The only problem I could see now is if a user tries a username/password and selects "remember me", but then closes their browser. The BreadCrumbFilter will keep trying to authenticate them - yep, I just verified that that's a problem. It's also a problem when they enter an invalid password and select rememberMe.

One way to solve this is to not set the "rememberMe" and "password" cookies until someone has successfully authenticated. Maybe I could use the breadcrumbs in the BreadCrumbFilter to check the last URL accessed, and if it's already j_security_check, don't do the routing. Anyway, here's the code that does the heavy lifting in BreadCrumbFilter:

Cookie rememberMe = RequestUtil.getCookie(request, "rememberMe");
// check to see if the user is logging out, if so, remove the
// rememberMe cookie and password Cookie
if (request.getRequestURL().indexOf("logout") != -1 && 
	(rememberMe != null)) {
    if (log.isDebugEnabled()) {
        log.debug("deleting rememberMe-related cookies");
    }

    response =
        RequestUtil.deleteCookie(response,
                                 RequestUtil.getCookie(request,
                                                       "rememberMe"));
    response =
        RequestUtil.deleteCookie(response,
                                 RequestUtil.getCookie(request,
                                                       "password"));
}

if (request.getRequestURL().indexOf("login") != -1) {
    // container is routing user to login page, check for remember me cookie
    Cookie username = RequestUtil.getCookie(request, "username");
    Cookie password = RequestUtil.getCookie(request, "password");

    if ((rememberMe != null) && (password != null)) {
        // authenticate user without displaying login page
        String route =
            "j_security_check?j_username=" +
            RequestUtils.encodeURL(username.getValue()) +
            "&j_password=" +
            RequestUtils.encodeURL(password.getValue());

        if (log.isDebugEnabled()) {
            log.debug("I remember you '" + username.getValue() +
                      "', authenticating...");
        }

        response.sendRedirect(response.encodeRedirectURL(route));

        return;
    }
}

I can post the code for RequestUtil if you need it. The class RequestUtils (for encoding URLs) is a Struts class.

Posted in Java at Jan 14 2003, 06:07:21 AM MST 4 Comments
Comments:

Matt - nice work! Which application server are you using? Tomcat? Does it do a server-side forward or redirect to the login page? And then how does it take you to the page you originally requested? JBoss does a redirect in both cases, which means you lose the request parameters and a Filter wouldn't catch them. Unless I'm missing something obvious.

Posted by Erik Hatcher on January 14, 2003 at 07:48 AM MST #

also, does redirecting to j_security_check work in other application servers? I don't believe that is going to work across vendors, because the spec says that the user must go to a protected resource first, and if you redirect directly to j_security_check then things might not work. this is just a hunch. keep me posted on your progress with this! i'm eagerly tuning in....

Posted by Erik Hatcher on January 14, 2003 at 07:51 AM MST #

To answer your first question: I am using Tomcat - and I've only tested this on WinXP, Win2K and Tomcat 4.1.18. Tomcat seems to do a redirect, as login.jsp shows up in the address bar. It just *knows* the page I originally requested, I'm not able to retrieve this value in any way. I'm not relying in any request parameters to make this happen, so redirects don't affect me. One thing I am doing on authentication is I have my login form mapped to "/auth/" rather than j_security_check. I have a servlet mapped to "auth" that does SSL redirect/password encryption - but it eventually redirects to j_security_check. I don't know that redirecting to j_security_check will work in all app servers - try it! It should - one way to verify is to check your login form's "action" value to see if it's still "j_security_check" when your login.jsp loads. I know that iPlanet used to replace "j_security_check" with it's own value. In order to workaround my bad password problem - I ended up creating another cookie called "authenticated" that only gets set in my ActionFilter. ActionFilter is mapped to the same URL as my protected resources. Then in BreadCrumbFilter, I ensure that the following cookies are set: rememberMe, password, authenticated. All this seems to be working pretty well for me. I'm lucky in that I only need to support Tomcat in the current projects I'm on.

Posted by Matt Raible on January 14, 2003 at 09:10 AM MST #

response.sendRedirect(response.encodeRedirectURL(route)); is really not a good idea, you are sending the password in the URL better would be to use forward of the servlet container instead

Posted by peter on February 21, 2003 at 01:40 PM MST #

Post a Comment:
  • HTML Syntax: Allowed