Bug 68677 - no support for enviroment variables/request attributes
Summary: no support for enviroment variables/request attributes
Status: NEW
Alias: None
Product: Tomcat Connectors
Classification: Unclassified
Component: isapi (show other bugs)
Version: 1.2.49
Hardware: PC All
: P2 enhancement (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-02-26 16:43 UTC by dub357
Modified: 2024-02-28 20:44 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dub357 2024-02-26 16:43:43 UTC
The Tomcat connector for IIS (isai filter) provides no support for passing request attributes from IIS to Tomcat other some hard-coded SSL-related ones.  This functionality is available in the mod_jk connector for Apache HTTP Server via the JkEnvVar directive.  I would like to see this extended to the IIS connector.  There are times when other modules/filters are running in IIS and setting request attributes, but these attributes are never available to backend Tomcat code because the connector doesn't pass them along.
Comment 1 dub357 2024-02-26 16:45:14 UTC
The Tomcat connector for IIS (isai filter) provides no support for passing request attributes from IIS to Tomcat other THAN some hard-coded SSL-related ones.  This functionality is available in the mod_jk connector for Apache HTTP Server via the JkEnvVar directive.  I would like to see this extended to the IIS connector.  There are times when other modules/filters are running in IIS and setting request attributes, but these attributes are never available to backend Tomcat code because the connector doesn't pass them along.
Comment 2 Christopher Schultz 2024-02-27 14:34:17 UTC
Does IIS have the ability to add request headers to proxied requests? For example, if you were using client -> [HTTP] -> IIS -> [HTTP] -> Tomcat, would you be able to set arbitrary HTTP headers into the request between IIS -> Tomcat?

I'm asking because AJP is really a protocol that should be retired and replaced with HTTP(S). If you can switch to HTTP and the tools you need exist when using it, all the better.
Comment 3 dub357 2024-02-27 16:31:52 UTC
I'm not entirely sure, but the point here is that I dont want to use on HTTP headers.  The current ISAPI filter already passes on those.  The problem is that they can be spoofed by the client so I'm hoping for a solution that would be able to supply request attributes to Tomcat like what the mod_jk JkEnvVar directive does. 

A reverse proxy setup like what you are describing isn't going to be able to do what I'm asking for because I need something that is integrated w/ Tomcat and can supply attributes to the backend HttpServletRequest.  Thats exactly what the Tomcat AJP connectors do.  However, only the Apache one (mod_jk) does this with user-defined attributes.
Comment 4 Christopher Schultz 2024-02-28 17:49:54 UTC
The typical way to do this is:

1. Remove all inbound HTTP headers you want to set at the proxy
2. Set your specific HTTP headers at the proxy
3. Read your now-trusted HTTP headers from the request in Tomcat

Can I direct you to https://tomcat.apache.org/presentations.html#latest-migrate-ajp-http for the "Migrating AJP -> HTTP" presentation?
Comment 5 dub357 2024-02-28 18:42:00 UTC
Again - I need something integrated w/ Tomcat and a true reverse proxy over HTTP will never be that.  How would things like REMOTE_USER or the client certificate get propagated to Tomcat?  This is something your presentation fails to discuss and is arguably the biggest advantage of AJP over other protocols.
Comment 6 Christopher Schultz 2024-02-28 19:22:29 UTC
(In reply to dub357 from comment #5)
> How would things like REMOTE_USER or the client
> certificate get propagated to Tomcat?  This is something your presentation
> fails to discuss and is arguably the biggest advantage of AJP over other
> protocols.

Slide 30 recommends using SSLValve specifically to handle client certificates.

I think REMOTE_USER is not handled by any component other than the AJP connector at this point. There is certainly room for improvement, there.
Comment 7 dub357 2024-02-28 19:30:19 UTC
Im stuck with IIS, hence the request for a mod to the isapi filter connector. If I could use Apache, I would be able to use the JkEnvVar directive.
Comment 8 Christopher Schultz 2024-02-28 19:55:10 UTC
I've proposed making arrangements for REMOTE_USER on the dev list. I realize that's not quite what you are asking for, here, but I thought I'd mention it since I really do think we as a community should move away from AJP.
Comment 9 Christopher Schultz 2024-02-28 19:59:41 UTC
Back to your original request...

Could you set HTTP headers (to proxy either using AJP or HTTP) and then have your application pick those up using a Filter? Something like:

Client -- HTTP --> IIS
IIS adds header Request-Attribute-Foo
IIS adds header Request-Attribute-Bar
IIS -- AJP or HTTP --> Tomcat
RequestAttributeFilter grabs all Request-Attribute-* headers
- request.setAttribute("Foo", request.getHeader("Request-Attribute-Foo"))
- request.setAttribute("Bar", request.getHeader("Request-Attribute-Bar"))

I guess what I'm really asking is "do you need this to be implemented in mod_jk or can you do it another way?"

The reason REMOTE_USER, etc. really need to be done differently is because you really want the REMOTE_USER and friends to be available as early as possible in the request-processing pipeline. That's why you would usually use a Valve for these kinds of things, including before any Authenticator valve runs.

If your application just needs some request attributes, can you grab them this way? Or, maybe even get them directly from the request headers instead of attributes?
Comment 10 dub357 2024-02-28 20:44:36 UTC
First off, what I'm asking for already exists in mod_jk via the JkEnvVar directive.  I just want the same thing for jk_isapi_plugin (the IIS equivalent of mod_jk).

This request stemmed from a deep dive into an issue I've been researching related to IIS and Adobe ColdFusion.  ColdFusion installs the Tomcat connector for the server that its set up to run within.  I think you run it by itself (basically running Tomcat by itself) but its recommended to run within a web server for additional security (lord knows its a target vector) and ease of setup.  For my organization, that server is IIS so it installs the IIS connector (isapi_redirect.dll) and requests get sent through IIS to ColdFusion/Tomcat via AJP.  This is an out-of-the-box install.

Now - we have another module/filter installed in IIS which handles SAML authentication called Shibboleth Service Provider.  By default, the Shibboleth SP software manipulates the request and after its performed authentication of the user, it stores REMOTE_USER and information about how they authenticated in request attributes/variables. Those attributes are made available to applications as part of the environment.  For things like PHP, you can access them via $_SERVER["some_var"].  For ASP, its request.ServerVariables("some_var") for Java/JSP its httpServletRequest.getAttribute("some_var").

Because the IIS connector doesn't pass any of this information on to Tomcat, I cannot access it within my ColdFusion code.  Luckily the Shibboleth SP software has an option to store the information in request headers, but it strongly recommended to not do this because those can be spoofed by the client.

So long story short, I absolutely need REMOTE_USER from IIS so I need AJP.  The jk_isapi_plugin provides this (yay).  However I cannot access the request variables that other modules/filters may set in IIS.  For Shibboleth SP, I'm forced to tell it to store the information in headers - a security risk arguably more severe than using AJP.