Struts 2
  1. Struts 2
  2. WW-2025

Action's can't be used for web.xml declarative security URL's

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Not a Problem
    • Affects Version/s: 2.0.8
    • Fix Version/s: Future
    • Component/s: Dispatch Filter
    • Labels:
      None
    • Environment:

      Tomcat 5.5.23 (also present in the most recent 6.0.13 release), Java(TM) SE Runtime Environment (build 1.6.0-b105), S2.0.8

      Description

      Using an action URI for web.xml declarative security results in a 404 "The requested resource (/mywebapp/login.action) is not available message." on Tomcat (both 5.5.x & 6.x). Representative XML configs below:

      <login-config>
      <auth-method>FORM</auth-method>
      <form-login-config>
      <form-login-page>/login.action</form-login-page>
      <form-error-page>/loginFailure.action</form-error-page>
      </form-login-config>
      </login-config>

      <action name="login">
      <result>/login.jsp</result>
      </action>

      Unfortunately it looks like the S2 architectural change from a Servlet to Servlet Filters is the culprit. After digging through the tomcat 5.5.23 (also present in the most recent 6.0.13 release) code I've come to the conclusion Struts2 actions CAN NOT be used for any of the common web.xml descriptor elements (form-login-page, form-error-page, welcome-file?, other?). Here's a snippet of the javadoc from org.apache.catalina.core.ApplicationDispatcher's invoke method:

      • <strong>IMPLEMENTATION NOTE</strong>: This implementation assumes that no filters are applied to a forwarded or included resource, because they were already done for the original request.

      Since this worked in S1, I've opened this ticket as a BUG. The workaround I received on the user list of doing an HTTP meta REFRESH works, but results in screen flashing (even with a refresh of 0 seconds) and a poor user experience. I'd GREATLY appreciate if one of the Struts developers had a more elegant workaround suggestion. For example would it be feasible to port FilterDispatcher to a servlet?

        Activity

        Hide
        Will Bagby added a comment -

        Having the same issue, using Tomcat 6.0.13. Seeking an elegant workaround as well...

        Show
        Will Bagby added a comment - Having the same issue, using Tomcat 6.0.13. Seeking an elegant workaround as well...
        Hide
        Maxx added a comment -

        Hello!

        Could this issue be related to this one: https://issues.apache.org/struts/browse/WW-1969 ??

        Thanks,
        Maxx

        Show
        Maxx added a comment - Hello! Could this issue be related to this one: https://issues.apache.org/struts/browse/WW-1969 ?? Thanks, Maxx
        Hide
        Maxx added a comment -

        Hello,

        I just tryed the same kind of thing (<form-login-config>) but without leading slash "/":
        <form-login-config>
        <form-login-page>Login.action</form-login-page>
        <form-error-page>Login.action</form-error-page>
        </form-login-config>
        (for the moment, i use the same classes/pages for login & error)
        I also created a "Login" action class (extending ActionSupport) which returns INPUT as a result of execute().
        And it WORKED !!!

        But for the moment, I can't reproduce the same redirection made by the Servlet, which happens when you called whatever page requiring login (through this "form-login-page"). I'm working on it.

        Show
        Maxx added a comment - Hello, I just tryed the same kind of thing (<form-login-config>) but without leading slash "/": <form-login-config> <form-login-page>Login.action</form-login-page> <form-error-page>Login.action</form-error-page> </form-login-config> (for the moment, i use the same classes/pages for login & error) I also created a "Login" action class (extending ActionSupport) which returns INPUT as a result of execute(). And it WORKED !!! But for the moment, I can't reproduce the same redirection made by the Servlet, which happens when you called whatever page requiring login (through this "form-login-page"). I'm working on it.
        Hide
        Ted Husted added a comment -

        Setting Fix Version to "future" for issues without a set fix version.

        Show
        Ted Husted added a comment - Setting Fix Version to "future" for issues without a set fix version.
        Hide
        Dean Pullen added a comment -

        I had the same problem.
        Changing my web.xml struts filter mapping, from:

        <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
        </filter-mapping>

        To:

        <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
        <!-- Must have these two dispatchers or /unsec/Login.action won't be found -->
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        </filter-mapping>

        Allowed the Login.action to be found.

        Show
        Dean Pullen added a comment - I had the same problem. Changing my web.xml struts filter mapping, from: <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> To: <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> <!-- Must have these two dispatchers or /unsec/Login.action won't be found --> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> Allowed the Login.action to be found.
        Hide
        Dean Pullen added a comment -

        Except the above seems to break IE7 - it will report a 404 on j_security_check

        Show
        Dean Pullen added a comment - Except the above seems to break IE7 - it will report a 404 on j_security_check
        Hide
        Dean Pullen added a comment -

        I've removed
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>

        And instead forwarded the login to a login_redirect.jsp:

        <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>Applications</realm-name>
        <form-login-config>
        <form-login-page>/login_redirect.jsp</form-login-page>
        <form-error-page>/login_redirect.jsp?success=false</form-error-page>
        </form-login-config>
        </login-config>

        The login_redirect.jsp contains:
        response.sendRedirect("/unsec/Login.action");

        This all seems to work fine, but it's obviously still a slight fudge.

        Show
        Dean Pullen added a comment - I've removed <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> And instead forwarded the login to a login_redirect.jsp: <login-config> <auth-method>FORM</auth-method> <realm-name>Applications</realm-name> <form-login-config> <form-login-page>/login_redirect.jsp</form-login-page> <form-error-page>/login_redirect.jsp?success=false</form-error-page> </form-login-config> </login-config> The login_redirect.jsp contains: response.sendRedirect("/unsec/Login.action"); This all seems to work fine, but it's obviously still a slight fudge.
        Hide
        Dmitry Kozlov added a comment -

        I've tested this on jetty 6.7.1. It works without any problems.

        Show
        Dmitry Kozlov added a comment - I've tested this on jetty 6.7.1. It works without any problems.
        Hide
        Héctor López Fernández added a comment -

        It's not Struts specific, it happens with every filter in web.xml. It seems a bug in some container's mapping methods, but i'm no expert on the spec...

        I'm having this issue in latest tomcat using a welcome-file. My workaround is a simple redirect servlet, but it has to be mapped for all the directory indexes i have...

        You can try this little test...

        [web.xml]

        <?xml version="1.0" encoding="UTF-8"?>
        <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

        <display-name>test</display-name>

        <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        </welcome-file-list>

        <filter>
        <filter-name>indexredirect</filter-name>
        <filter-class>org.mytest.IndexRedirectFilter</filter-class>
        </filter>
        <filter-mapping>
        <filter-name>indexredirect</filter-name>
        <url-pattern>/index.html</url-pattern>
        </filter-mapping>

        </web-app>

        [Filter class]

        package org.mytest;

        public class IndexRedirectFilter implements Filter {
        public void destroy() {
        }

        public void doFilter(ServletRequest arg0, ServletResponse response,
        FilterChain arg2) throws IOException, ServletException {
        if (response instanceof HttpServletResponse)

        { ((HttpServletResponse)response).sendRedirect("index.action"); }

        }

        public void init(FilterConfig arg0) throws ServletException {
        }
        }

        You'll never get redirected to index.action

        Show
        Héctor López Fernández added a comment - It's not Struts specific, it happens with every filter in web.xml. It seems a bug in some container's mapping methods, but i'm no expert on the spec... I'm having this issue in latest tomcat using a welcome-file. My workaround is a simple redirect servlet, but it has to be mapped for all the directory indexes i have... You can try this little test... [web.xml] <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd " id="WebApp_ID" version="2.5"> <display-name>test</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <filter> <filter-name>indexredirect</filter-name> <filter-class>org.mytest.IndexRedirectFilter</filter-class> </filter> <filter-mapping> <filter-name>indexredirect</filter-name> <url-pattern>/index.html</url-pattern> </filter-mapping> </web-app> [Filter class] package org.mytest; public class IndexRedirectFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain arg2) throws IOException, ServletException { if (response instanceof HttpServletResponse) { ((HttpServletResponse)response).sendRedirect("index.action"); } } public void init(FilterConfig arg0) throws ServletException { } } You'll never get redirected to index.action
        Hide
        musachy added a comment -

        This doesn't seems like a struts specific problem. If you still think it is, drop an email on the dev mailing list and we can discuss it.

        Show
        musachy added a comment - This doesn't seems like a struts specific problem. If you still think it is, drop an email on the dev mailing list and we can discuss it.

          People

          • Assignee:
            Unassigned
            Reporter:
            Jon Wilmoth
          • Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development