vendredi 12 juin 2015

Persistent authentication filter logging in; not propagating to JSP

I've been working on a "Remember Me?"-style persistent authentication system, but after successfully authenticating and logging in the user, my JSPs do not reflect that the user is logged in until the next page request or refresh is processed. The cookie used for this is being written, and the database is being updated. Checking the login state of the user object within the Filter method indicates that the user object is being properly loaded. After refreshing or navigating to a different page, the page shows that the user is logged in.

Why does the successful login not show up on the first page?

Is there something obvious that I'm not doing here, that would prevent changes to the session data from within a Filter from being propagated to the JSP? Is this a limitation that needs to be overcome by a forced refresh?

This is written for a Java EE 5 and Struts 1.x site rendering to JSPs, using a custom Java EE Filter class as the entry point for automatic login. The filter is installed first in the chain, and mapped to "/*" in my web.xml.

My filter method implementation looks like this:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
    if (!isPersistentAuthEnabled()) {
        chain.doFilter(req, resp);
        return;
    }
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;
    HttpSession session = request.getSession(false);

    SessionStore store = null;
    if (session != null) {
        store = (SessionStore)session.getAttribute("sessionStore");
    }

    User user = null;
    if (store != null) {
        user = store.getUser();
    }

    if (user == null || user.isLoggedIn()) {
        // Skip authentication if no user object in session, or if already logged in.
        chain.doFilter(req, resp);
        return;
    }

    PersistentAuthenticationManager manager = null;
    try {
        manager = new PersistentAuthenticationManager();
    } catch (Exception e) {
        LOG.warn("skipping");
        chain.doFilter(req, resp);
        return;
    }

    try {
        manager.authenticateUser(user, request, response); // Authenticates based on cookie and DB store
        if (user.isLoggedIn()) {
            LOG.debug("success"); // this is being logged correctly
        }
    } catch (Exception e) {
        LOG.warn("failure");
    }
    chain.doFilter(req, resp);
}

The relevant code in the JSP is as follows (mapping the taglib jstl-core.tld to the c prefix):

<c:choose>
    <c:when test="${sessionStore.user.loggedIn}">
        <!-- Not shown: Display welcome message -->
    </c:when>
    <c:otherwise>
        <!-- Not shown: Click here to log in -->
    </c:otherwise>
</c:choose>

I've tested this on Chrome and IE so far, and the same thing happens on both. My idea for a fix would be to force a refresh by redirecting the user to the same page, but I fear that might have some ill effects, such as if that were to hit the Struts action handlers for certain requests (ie. posting things) before submitting a redirect, among other doubts. Is there some other way to handle this scenario?

Aucun commentaire:

Enregistrer un commentaire