-----------
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

Reply via email to