----------- Description ----------- I have a web app that is a collection of a few web apps, with a structure like:
- apache-tomcat - myWebSite - webapps - web app #1 (login) - web app #2 - ... ... - web app #X I use Tomcat SingleSignOn valve for moving around the web apps with one authentication. However, Tomcat single sign on stop working after I set the parameter STRICT_SERVLET_COMPLIANCE to true. I tried to look up the use of STRICT_SERVLET_COMPLIANCE with Tomcat 9 but didn't find much info related to the cookie issue I encountered. ----- Setup ----- 1. Tomcat 9.0.62 2. Java: OpenJDK 8u332 3. OS: Red Hat Enterprise Linux 8.4 4. Browser Client: Firefox (102.0.1, 64-bit)/Chrome (103.0.5060.114, 64-bit). 5. The Host config (partial) in Tomcat server.xml: <Host appBase="myWebSite/webapps" name="localhost" unpackWARs="true"> <Valve className="org.apache.catalina.authenticator.SingleSignOn"/> ... ... </Host> ------- Details ------- The behavior is supposed to be: 1. User accesses the web app and gets redirected to the login page. The login is handled by web app #1. 2. After successful login, user is supposed to be redirected to a page that is handled by web app #2. What actually happened is: 1. User accesses the web app and gets redirected to the login page. The login is handled by web app #1. 2. After successful login, user gets redirected to a page that is handled by web app #2. However, the single sign on cookie was not sent in the request to the page handled by web app #2. 3. So the user gets redirected to the login page handled by web app #1. 4. The single sign on cookie was present in the request to the login page handled by web app #1. So it does not ask the user to login again. Then the user gets redirected to the page handled by web app #2. 5. It keep repeating the steps between Steps 2-4. The observations are: 1. If the parameter STRICT_SERVLET_COMPLIANCE is false (default): (a) the single sign on cookie is present in the requests to the web app(s) so no additional authentication is required when moving around web apps after successful login. (b) The path in the cookie is root web app that looks like "/" in the browser developer tool. 2. If the parameter STRICT_SERVLET_COMPLIANCE is true: (a) the signle sign on cookie is present ONLY in the requests to the web app #1 that handles the login authentication. (b) the path in the cookie is root web app but with additional double-quotes "\"/\"". This issue is observed in Firefox (102.0.1, 64-bit) and Chrome (103.0.5060.114, 64-bit). According to Tomcat 9 documentation for STRICT_SERVLET_COMPLIANCE at: https://tomcat.apache.org/tomcat-9.0-doc/config/systemprops.html#Security Setting the parameter STRICT_SERVLET_COMPLIANCE affects a number of other parameters. So I tried to set the affected parameters back to default after setting STRICT_SERVLET_COMPLIANCE as true like below: -Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE=true -Dorg.apache.catalina.core.ApplicationContext.GET_RESOURCE_REQUIRE_SLASH=false -Dorg.apache.catalina.core.ApplicationDispatcher.WRAP_SAME_OBJECT=false -Dorg.apache.catalina.core.StandardHostValve.ACCESS_SESSION=false -Dorg.apache.catalina.session.StandardSession.ACTIVITY_CHECK=false -Dorg.apache.catalina.session.StandardSession.LAST_ACCESS_AT_START=false -Dorg.apache.tomcat.util.http.ServerCookie.STRICT_NAMING=false -Dorg.apache.tomcat.util.http.ServerCookie.ALWAYS_ADD_EXPIRES=true -Dorg.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR=false In theory, that would negate the affect from STRICT_SERVLET_COMPLIANCE being true. However, the behavior is the same- Tomcat single sign on still breaks. I compared the documentation about STRICT_SERVLET_COMPLIANCE between Tomcat 8 (at https://tomcat.apache.org/tomcat-8.0-doc/config/systemprops.html#Security) and Tomcat 9. I found: For Tomcat 8, 8 system properties will be affected by STRICT_SERVLET_COMPLIANCE being true. For Tomcat 9, 6 system properties will be affected by STRICT_SERVLET_COMPLIANCE being true (no org.apache.tomcat.util.http.ServerCookie.ALWAYS_ADD_EXPIRES and org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR). In Tomcat 8 documentation, it notes: "Note that changing a number of the above defaults is likely to break the majority of systems as some browsers are unable to correctly handle the cookie headers that result from a strict adherence to the specifications. Defaults, regardless of whether or not they have been changed by setting org.apache.catalina.STRICT_SERVLET_COMPLIANCE can always be overridden by explicitly setting the appropriate system property or element attribute." There is no such note in Tomcat 9 documentation. Apparently, explicitly setting the appropriate system property or element attribute does not override the effect by setting as STRICT_SERVLET_COMPLIANCE true. I checked the source code of Tomcat 9.0.62 and found some flags merely depends on the value of STRICT_SERVLET_COMPLIANCE. But I am not sure how those related code affects cookie handling. The cookies are shared among requests when STRICT_SERVLET_COMPLIANCE is false as default. When STRICT_SERVLET_COMPLIANCE is true, cookies in the responses from web app #1 are not seen in requests to web app #2. I wonder whether setting STRICT_SERVLET_COMPLIANCE as true is also likely to break the majority of systems with Tomcat 9? If not, is there anything I missed here? If yes, would it be nice to add the note in Tomcat 8 documentation to Tomcat 9 too? Any comment or guidance is much appreciated. Thanks in advance. Regards, Wenshiuan Tang