Jetspeed 2
  1. Jetspeed 2
  2. JS2-828

JAAS authentication failure with Tomcat 5.5.24 and above.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.2.0
    • Component/s: None
    • Labels:
      None
    • Environment:
      Tomcat >= 5.5.24

      Description

      Immediately after logging into the portal, the URL address box in the browser displays:
      http://localhost:20000/jetspeed/login/redirector
      ======================
      And the page displays:
      HTTP Status 403 - Access to the requested resource has been denied

      type Status report

      message Access to the requested resource has been denied

      description Access to the specified resource (Access to the requested resource has been denied) has been forbidden.
      Apache Tomcat/5.5.25
      ======================
      I believe this is the same behavior in Tomcat 6.0.x and I get the same thing in GlassFish v2-b58g.

      This does NOT happen in Tomcat 5.5.23 or lower versions. Something changed between 5.5.23 and 5.5.25.
      Also, after the login post if you just type in the URL http://<>/jetspeed, the page appears normally and you can
      function.

      I do not know whether it is relevant but at least GlassFish appears to record the following in the server.log.

      Unable to set request character encoding to UTF-8 from context /jetspeed, because request parameters have already been read, or ServletRequest.getReader() has already been called

        Activity

        Hide
        Ate Douma added a comment - - edited

        Confirmed.

        And I also found why: http://issues.apache.org/bugzilla/show_bug.cgi?id=40150
        This is a patch applied to Tomcat 5.5.24 (and 6, I haven't yet figured out since which version).
        The point of the above issue was detecting invalid Principal classes (which couldn't be loaded) so to provide proper feedback during startup of Tomcat.
        But, this patch didn't cater for another feature of the JAASRealm, namely that these Principal classes can be located/provided by the specific web application itself (configuration parameter useContextClassLoader, default true).
        The check done on the provided classes is not done with respect to this configuration parameter, thus now fails with Jetspeed which depends on this
        So, our Principal classes are no longer known to Tomcat and thus its container authentication is completely broken!

        I'll pursuit this issue with the Tomcat team and see if we can get this patch reversed or corrected, but for the time being its difficult to run Jetspeed on Tomcat >= 5.5.24.
        A workaround is extracting the JaasReam.class from the catalina-optional.jar from Tomcat 5.5.23 and copy that (in the proper package directory) under $TOMCAT_HOME/server/classes.
        I've tested it out and it works (the above patch is the only change to this class so far).

        As this issue isn't related to jetspeed at all but really a Tomcat bug, I'm going to remove the Fix version as its not something we cann fix.

        Show
        Ate Douma added a comment - - edited Confirmed. And I also found why: http://issues.apache.org/bugzilla/show_bug.cgi?id=40150 This is a patch applied to Tomcat 5.5.24 (and 6, I haven't yet figured out since which version). The point of the above issue was detecting invalid Principal classes (which couldn't be loaded) so to provide proper feedback during startup of Tomcat. But, this patch didn't cater for another feature of the JAASRealm, namely that these Principal classes can be located/provided by the specific web application itself (configuration parameter useContextClassLoader, default true ). The check done on the provided classes is not done with respect to this configuration parameter, thus now fails with Jetspeed which depends on this So, our Principal classes are no longer known to Tomcat and thus its container authentication is completely broken! I'll pursuit this issue with the Tomcat team and see if we can get this patch reversed or corrected, but for the time being its difficult to run Jetspeed on Tomcat >= 5.5.24. A workaround is extracting the JaasReam.class from the catalina-optional.jar from Tomcat 5.5.23 and copy that (in the proper package directory) under $TOMCAT_HOME/server/classes. I've tested it out and it works (the above patch is the only change to this class so far). As this issue isn't related to jetspeed at all but really a Tomcat bug, I'm going to remove the Fix version as its not something we cann fix.
        Hide
        Ate Douma added a comment -

        FYI: I just reopened the Tomcat bug 40150 which resolution is the cause of this problem:
        http://issues.apache.org/bugzilla/show_bug.cgi?id=40150

        Show
        Ate Douma added a comment - FYI: I just reopened the Tomcat bug 40150 which resolution is the cause of this problem: http://issues.apache.org/bugzilla/show_bug.cgi?id=40150
        Hide
        Ate Douma added a comment -

        According to the Tomcat developers this should be fixed with the next Tomcat 5.5.x and 6.x releases.
        See also: http://issues.apache.org/bugzilla/show_bug.cgi?id=44084

        Show
        Ate Douma added a comment - According to the Tomcat developers this should be fixed with the next Tomcat 5.5.x and 6.x releases. See also: http://issues.apache.org/bugzilla/show_bug.cgi?id=44084
        Hide
        Vivek Kumar added a comment -

        This issue is caused by tomcat. Tomcat people have fixed this issue in Tomcat release 5.5.26.
        I marking this issue as resolved.

        Show
        Vivek Kumar added a comment - This issue is caused by tomcat. Tomcat people have fixed this issue in Tomcat release 5.5.26. I marking this issue as resolved.
        Hide
        Prasanna added a comment -

        What about Glassfish?

        It looks like it still not fixed in Glassfish.

        Thanks
        Prasana

        Show
        Prasanna added a comment - What about Glassfish? It looks like it still not fixed in Glassfish. Thanks Prasana
        Hide
        David Sean Taylor added a comment -

        I just tried this on 5.5.26. It is still broken:

        Jun 24, 2008 3:41:18 PM org.apache.catalina.realm.JAASRealm parseClassNames
        SEVERE: Class org.apache.jetspeed.security.impl.UserPrincipalImpl not found! Class not added.
        Jun 24, 2008 3:41:18 PM org.apache.catalina.realm.JAASRealm parseClassNames
        SEVERE: Class org.apache.jetspeed.security.impl.RolePrincipalImpl not found! Class not added.

        Show
        David Sean Taylor added a comment - I just tried this on 5.5.26. It is still broken: Jun 24, 2008 3:41:18 PM org.apache.catalina.realm.JAASRealm parseClassNames SEVERE: Class org.apache.jetspeed.security.impl.UserPrincipalImpl not found! Class not added. Jun 24, 2008 3:41:18 PM org.apache.catalina.realm.JAASRealm parseClassNames SEVERE: Class org.apache.jetspeed.security.impl.RolePrincipalImpl not found! Class not added.
        Hide
        David Sean Taylor added a comment -

        additionally, when i go to login, the login module is not found (under 5.5.26):

        WARNING: Login exception authenticating username "admin"
        javax.security.auth.login.LoginException: unable to find LoginModule class: org.apache.jetspeed.security.impl.DefaultLoginModule

        Show
        David Sean Taylor added a comment - additionally, when i go to login, the login module is not found (under 5.5.26): WARNING: Login exception authenticating username "admin" javax.security.auth.login.LoginException: unable to find LoginModule class: org.apache.jetspeed.security.impl.DefaultLoginModule
        Hide
        David Sean Taylor added a comment -

        By setting the context.xml "useContextClassLoader" attribute = true, this is now working in 5.5.26

        <Realm className="org.apache.catalina.realm.JAASRealm"
        appName="Jetspeed"
        userClassNames="org.apache.jetspeed.security.impl.UserPrincipalImpl"
        roleClassNames="org.apache.jetspeed.security.impl.RolePrincipalImpl"
        useContextClassLoader="true"
        debug="0"/>

        I just commited a patch to the context.xml

        I am considering this issue resolved now. I have not tested on Glassfish or Tomcat 6
        Please create new issues for Glassfish and Tomcat 6 if the problem exists there

        Show
        David Sean Taylor added a comment - By setting the context.xml "useContextClassLoader" attribute = true, this is now working in 5.5.26 <Realm className="org.apache.catalina.realm.JAASRealm" appName="Jetspeed" userClassNames="org.apache.jetspeed.security.impl.UserPrincipalImpl" roleClassNames="org.apache.jetspeed.security.impl.RolePrincipalImpl" useContextClassLoader="true" debug="0"/> I just commited a patch to the context.xml I am considering this issue resolved now. I have not tested on Glassfish or Tomcat 6 Please create new issues for Glassfish and Tomcat 6 if the problem exists there
        Hide
        David Sean Taylor added a comment -

        Note: changing useContextClassLoader="true" now breaks 5.5.20 (I have not tested with each and every Tomcat version)
        To summarize, recommend:

        All new development on the 2.2 trunk should be done with 5.5.26 or higher
        If you want to develop with the 2.2 and use 5.5.23 or lower, change the useContextClassLoader='false'

        Do not use versions 5.5.24 or 5.5..25 as they are broken with the way Jetspeed creates its own realm

        Show
        David Sean Taylor added a comment - Note: changing useContextClassLoader="true" now breaks 5.5.20 (I have not tested with each and every Tomcat version) To summarize, recommend: All new development on the 2.2 trunk should be done with 5.5.26 or higher If you want to develop with the 2.2 and use 5.5.23 or lower, change the useContextClassLoader='false' Do not use versions 5.5.24 or 5.5..25 as they are broken with the way Jetspeed creates its own realm
        Hide
        orbit websig added a comment -

        Thought I'd share my experience with getting JAAS/Tomcat 6/Eclipse working. Not everything in here is crucial to your implementation, but I figured this post will at least put it all together. Many articles and blogs left me frustrated with just covering pieces of the solution, and not showing me the necessary connections between them.

        To begin, I installed Java (say version 6.0 or better), and then Eclipse (or MyEclipse, if you like). Then I updated Eclipse with the Subversive plug-in, to access my subversion repository to persist and pull my code onto different machines as I travel.
        (e.g. https://failship.company.com/repo).

        Upon checkout, I created a Dynamic Web Project or whatever name Eclipse provides for a basic web application. Take your time here and step through each of the wizard screens, because some setting changes are subtle and have major pain-in-the-butt ripple effects.

        You'll have to create the basic LoginModule and Principal implementations to support your custom login code. That information was provided everywhere on the Web. My frustration was in putting it all together. Anyway, out of the scores of resources I used to investigate, I found this one to be pretty concise:

        http://blog.frankel.ch/tech/dev/java/jee/custom-loginmodule-in-tomcat

        If you are going to test with Tomcat 6.0, you must add the following tag to the conf/context.xml file.

        <Loader delegate="true"/>

        Otherwise, you might get some

        "java.lang.ClassCastException: org.apache.catalina.util.DefaultAnnotationProcessor cannot be cast to org.apache.AnnotationProcessor"

        exception.

        While you have context.xml open, you will have to add a 'Realm' for Container Security, to enable our LoginModule secure access. The 1st step is to enable the JaasRealm, typically by pasting in the existing entry as follows:

        <!-- Inserted to enable MyAccessLoginModule. You will have to launch tomcat
        with -Djava.security.auth.login.config= pointing to the jaas.config file: -->
        <Realm className="org.apache.catalina.realm.JAASRealm"
        appName="MyAccess"
        userClassNames="com.company.myAccess.realm.MyAccessUserPrincipal"
        roleClassNames="com.company.myAccess.realm.MyAccessRolePrincipal">
        </Realm>

        Next, I had to create a jaas.conf file to declare my LoginModule implementation. Notice that this has the same name as the "appName" provided in the <realm> definition above. Here's the contents of jaas.conf:

        /** Login Configuration for the JAAS Sample Application **/
        MyAccess

        { com.company.myAccess.realm.MyAccessLoginModule requisite debug=true; }

        ;

        The realm also needs to know how to find the jaas.config file and it does this through the Java system property, set as a JVM argument, for the variable "java.security.auth.login.config". You can set this, in eclipse by configuring a "Server", typically through the Window->Preference menu (or in MyEclipse under its preferences). The JVM takes a -D argument, to define the variable, as in:

        -Djava.security.auth.login.config=C:"/Documents and Settings/sandrews/Workspaces/MyEclipse Blue/myAccess-20090902/jaas.config"

        While you're here, you may want to add any custom defined variables for your web application. My LoginModule read the tomcat-users.xml file as well, so I designated it with the follow arguments:

        -DTomcatUsersXmlFile=C:"/Program Files/Apache Software Foundation/Tomcat 6.0/conf/tomcat-users.xml"

        Again, this last argument was custom to my application, so it's necessary for your web app.

        Next, edit the data source for your user authentication, as in conf/tomcat-users.xml, to add the role, say 'myAccess', and the user, like 'bsmith' for example:

        <tomcat-users>
        <role rolename="myAccess"/>
        <user name="bsmith" password="123qwe" roles="myRole"/>
        </tomcat-users>

        Your web application's WEB-INF/web.xml should set the security restrictions,
        as in:

        <!-- Define a Security Constraint on this Application -->
        <security-constraint>
        <web-resource-collection>
        <web-resource-name>Secured resources</web-resource-name>
        <url-pattern>/jsp/*</url-pattern>
        <url-pattern>/html/*</url-pattern>
        <url-pattern>/index.jsp</url-pattern>
        </web-resource-collection>
        <auth-constraint>
        <role-name>myRole</role-name>
        </auth-constraint>
        </security-constraint>
        <security-constraint>
        <web-resource-collection>
        <web-resource-name>Unsecured resources</web-resource-name>
        <url-pattern>/images/*</url-pattern>
        <url-pattern>/css/*</url-pattern>
        </web-resource-collection>
        </security-constraint>
        <security-role>
        <description>Role required to see admin pages.</description>
        <role-name>myRole</role-name>
        </security-role>
        <!-- Define the Login Configuration for this Application -->
        <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>MyAccess</realm-name>
        <form-login-config>
        <form-login-page>/jsp/userLoginForm.jsp</form-login-page>
        <form-error-page>/jsp/userLoginForm.jsp?action=error</form-error-page>
        </form-login-config>
        </login-config>

        Notice that the 'security-constraint' wraps a 'auth-constraint' which references a 'role-name' which maps to a 'security-role'.

        Lastly, I had to ensure that when the application server loads (not my web application, but the server), it has access to load my LoginModule implementation and supporting classes. Hence I used an ANT script to jar up my *.class files and deploy them under tomcat's lib directory, as in:

        lib/myAccess.jar

        This was key, and without it, I was left in the dark, not knowing that the WEB-INF/classes deployment (the default) was not enough. The realm is loaded before your web app, and needs to be ready with the data source connections open, etc. Once this was done, I was able to login using my custom LoginModule.

        Again, some of my frustrations were eleviated through the information found at:

        http://blog.frankel.ch/tech/dev/java/jee/custom-loginmodule-in-tomcat

        So some major Thanks go out to that Nicolas Frankel guy, and Good Luck!

        Show
        orbit websig added a comment - Thought I'd share my experience with getting JAAS/Tomcat 6/Eclipse working. Not everything in here is crucial to your implementation, but I figured this post will at least put it all together. Many articles and blogs left me frustrated with just covering pieces of the solution, and not showing me the necessary connections between them. To begin, I installed Java (say version 6.0 or better), and then Eclipse (or MyEclipse, if you like). Then I updated Eclipse with the Subversive plug-in, to access my subversion repository to persist and pull my code onto different machines as I travel. (e.g. https://failship.company.com/repo ). Upon checkout, I created a Dynamic Web Project or whatever name Eclipse provides for a basic web application. Take your time here and step through each of the wizard screens, because some setting changes are subtle and have major pain-in-the-butt ripple effects. You'll have to create the basic LoginModule and Principal implementations to support your custom login code. That information was provided everywhere on the Web. My frustration was in putting it all together. Anyway, out of the scores of resources I used to investigate, I found this one to be pretty concise: http://blog.frankel.ch/tech/dev/java/jee/custom-loginmodule-in-tomcat If you are going to test with Tomcat 6.0, you must add the following tag to the conf/context.xml file. <Loader delegate="true"/> Otherwise, you might get some "java.lang.ClassCastException: org.apache.catalina.util.DefaultAnnotationProcessor cannot be cast to org.apache.AnnotationProcessor" exception. While you have context.xml open, you will have to add a 'Realm' for Container Security, to enable our LoginModule secure access. The 1st step is to enable the JaasRealm, typically by pasting in the existing entry as follows: <!-- Inserted to enable MyAccessLoginModule. You will have to launch tomcat with -Djava.security.auth.login.config= pointing to the jaas.config file: --> <Realm className="org.apache.catalina.realm.JAASRealm" appName="MyAccess" userClassNames="com.company.myAccess.realm.MyAccessUserPrincipal" roleClassNames="com.company.myAccess.realm.MyAccessRolePrincipal"> </Realm> Next, I had to create a jaas.conf file to declare my LoginModule implementation. Notice that this has the same name as the "appName" provided in the <realm> definition above. Here's the contents of jaas.conf: /** Login Configuration for the JAAS Sample Application **/ MyAccess { com.company.myAccess.realm.MyAccessLoginModule requisite debug=true; } ; The realm also needs to know how to find the jaas.config file and it does this through the Java system property, set as a JVM argument, for the variable "java.security.auth.login.config". You can set this, in eclipse by configuring a "Server", typically through the Window->Preference menu (or in MyEclipse under its preferences). The JVM takes a -D argument, to define the variable, as in: -Djava.security.auth.login.config=C:"/Documents and Settings/sandrews/Workspaces/MyEclipse Blue/myAccess-20090902/jaas.config" While you're here, you may want to add any custom defined variables for your web application. My LoginModule read the tomcat-users.xml file as well, so I designated it with the follow arguments: -DTomcatUsersXmlFile=C:"/Program Files/Apache Software Foundation/Tomcat 6.0/conf/tomcat-users.xml" Again, this last argument was custom to my application, so it's necessary for your web app. Next, edit the data source for your user authentication, as in conf/tomcat-users.xml, to add the role, say 'myAccess', and the user, like 'bsmith' for example: <tomcat-users> <role rolename="myAccess"/> <user name="bsmith" password="123qwe" roles="myRole"/> </tomcat-users> Your web application's WEB-INF/web.xml should set the security restrictions, as in: <!-- Define a Security Constraint on this Application --> <security-constraint> <web-resource-collection> <web-resource-name>Secured resources</web-resource-name> <url-pattern>/jsp/*</url-pattern> <url-pattern>/html/*</url-pattern> <url-pattern>/index.jsp</url-pattern> </web-resource-collection> <auth-constraint> <role-name>myRole</role-name> </auth-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Unsecured resources</web-resource-name> <url-pattern>/images/*</url-pattern> <url-pattern>/css/*</url-pattern> </web-resource-collection> </security-constraint> <security-role> <description>Role required to see admin pages.</description> <role-name>myRole</role-name> </security-role> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>FORM</auth-method> <realm-name>MyAccess</realm-name> <form-login-config> <form-login-page>/jsp/userLoginForm.jsp</form-login-page> <form-error-page>/jsp/userLoginForm.jsp?action=error</form-error-page> </form-login-config> </login-config> Notice that the 'security-constraint' wraps a 'auth-constraint' which references a 'role-name' which maps to a 'security-role'. Lastly, I had to ensure that when the application server loads (not my web application, but the server), it has access to load my LoginModule implementation and supporting classes. Hence I used an ANT script to jar up my *.class files and deploy them under tomcat's lib directory, as in: lib/myAccess.jar This was key, and without it, I was left in the dark, not knowing that the WEB-INF/classes deployment (the default) was not enough. The realm is loaded before your web app, and needs to be ready with the data source connections open, etc. Once this was done, I was able to login using my custom LoginModule. Again, some of my frustrations were eleviated through the information found at: http://blog.frankel.ch/tech/dev/java/jee/custom-loginmodule-in-tomcat So some major Thanks go out to that Nicolas Frankel guy, and Good Luck!

          People

          • Assignee:
            Ate Douma
            Reporter:
            Mohan Kannapareddy
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development