https://issues.apache.org/bugzilla/show_bug.cgi?id=3839
--- Comment #14 from Mark Morris <mmor...@orgstrategies.com> 2010-10-06 15:29:58 EDT --- I've been tracing through the Tomcat source code because of an "Invalid direct reference to form login page" error our customers frequently get and here is what was found (for Tomcat 5 and 6): When you retrieve the login page for the first time, Tomcat initializes a field that is needed for the actual login (a session.note entry). Unfortunately that field is wiped out after the session expires or the server is rebooted. Also Tomcat confuses the get request for http://<server>/j_security_check with the actual login action (see further down for an explanation in extreme detail). As a workaround for this error, we implemented the following at the end of our login module (posted with permission from Organizational Strategies Inc): org.apache.catalina.connector.RequestFacade requestFacade = (RequestFacade)request; org.apache.catalina.connector.Request tomcatRequest = org.apache.catalina.connector.TomcatRequestFacadeAccessor.extractRequest(requestFacade); org.apache.catalina.Session tomcatSession = tomcatRequest.getSessionInternal(false); org.apache.catalina.authenticator.SavedRequest saved = (SavedRequest) tomcatSession.getNote(org.apache.catalina.authenticator.Constants.FORM_REQUEST_NOTE); if(saved==null){ saved = new SavedRequest(); saved.setRequestURI("/your/path/here"); tomcatSession.setNote(Constants.FORM_REQUEST_NOTE, saved); } You will also need to make a TomcatRequestFacadeAccessor class (in package org.apache.catalina.connector), jar it up and add that jar to Tomcat's classpath. That class contains this method public static org.apache.catalina.connector.Request extractRequest(RequestFacade facade){ return facade.request; } The above is just a quickly put-together workaround for the error. We're hoping someone will implement a permanent solution into the Tomcat codebase to address this issue. To assist with that below is an explanation of the error in extreme detail 1) After rebooting everything and going to the login page for the first time, the following code in org.apache.catalina.authenticator.FormAuthenticator.authenticate() gets executed: if (!loginAction) { session = request.getSessionInternal(true); if (log.isDebugEnabled()) log.debug("Save request in session '" + session.getIdInternal() + "'"); try { saveRequest(request, session); } catch (IOException ioe) { log.debug("Request body too big to save during authentication"); response.sendError(HttpServletResponse.SC_FORBIDDEN, sm.getString("authenticator.requestBodyTooBig")); return (false); } forwardToLoginPage(request, response, config); return (false); } The loginAction flag is true when you press the login button; however, the retrieving of the login page is NOT a loginAction so the above block executes 2) In that block of code, the call to saveRequest(request, session) eventually executes the following line: session.setNote(Constants.FORM_REQUEST_NOTE, saved); 3) Later on when you press the login button, this code in FormAuthenticator.java tries to use that session.note value: requestURI = savedRequestURL(session); and savedRequestURL returns the session.note value set when the login page was originally retrieved: session.getNote(Constants.FORM_REQUEST_NOTE); 4) Unfortunately if the block of code from 1) is not executed, then the session.note value won't be set, requestURI will be null and this will run, giving you the "Invalid direct reference to form login page" error: requestURI = savedRequestURL(session); if (requestURI == null) response.sendError(HttpServletResponse.SC_BAD_REQUEST, sm.getString("authenticator.formlogin")); 5) The block of code from 1) won't execute and you'll get the "Invalid direct reference to form login page" error in the following conditions: a) If the server is rebooted and the user already has a login window open b) If the user's session times out and they already have a login window open c) If they go directly to URL http://<yourserver>/your/path/here/j_security_check (many users may have this bookmarked because it's the browser URL you see after invalid logins) The reason this URL doesn't work is because the loginAction flag toggling the block of code from 1) is set like this: boolean loginAction = requestURI.startsWith(contextPath) && requestURI.endsWith(Constants.FORM_ACTION); //this is "/j_security_check" and going to http://<yourserver>/your/path/here/j_security_check will set loginAction to true (Tomcat thinks you clicked the login button) - one way to fix this is to make loginAction false for GET requests Many thanks in advance for whoever makes the FormAuthenticator changes to fix this. Thanks, Mark Morris. -- Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org