Hi Josh,
in my opinion you'll have three different options to meet your requirements...
Scenario 1: Modify your application
Don't get me wrong, I'm not kidding. But modifying your application is technically the best approach. In this case you would change the URIs once in your code, but not on every single HTTP request. But on the other hand, it would require you to change the application itself, which is not always possible... (e.g. when using 3rd Party software)
Scenario 2: Extend your ACL
Since you don't have any technical reason, to stick everything to the /users directory (e.g. no content switching requirements). You could basically allow additional but well selected /* resources, if they meet your security requirements.
Compared to the other scenarios, it would be much easier to simply extent your ACL, so that your users could transparently access the embedded content of those directories (e.g. /images, /css, etc.).
Depending on the sensitivity of the additional directories, you may allow the content either file-by-file, or by using wildcards for entire directories. In the end it doesn’t matter which URI was used to access a file, right? Just the access itself is security relevant...
Scenario 3: Rewrite HTTP Request and HTTP Responses
This is by far the most difficult way to access files outside of the /users directory. In this scenario you would map certain /* resources into a certain subfolder underneath of /users (e.g. /users/www-root/*).
To make this happen, you would need to parse every HTTP request and (un)translate the [HTTP::uri] and optionally the [HTTP::header referer]. So that...
Clientside /users/www-root/* would become Serverside /* for incomming requests
In addition to that you would need to parse every HTTP response and translate every [HTTP::header location], [HTTP::cookie] and last but not least the [HTTP::payload]. So that....
Serverside /* would become Clientside /users/www-root/* for outgoing responses
As difficult as the translation itself could be, the outlined technique "as is" is unfortunately not enough to meet your security requirements!
To provide the required security, you MUST somehow implement an additional mechanism to identify, which /* resources could be accessed using the new /users/www-root/* entry point.
This could achieved either by using ACLs (same overhead as scenario 2) or by using cryptography to sign/encrypt every translated outgoing URI and allow just those signed/encrypted URIs to access /* resources. So that...
Serverside /images/banner.jpg would become Clientside /users/www-root/JBAJXBJABCJBJJHDLDHLKDJNJDNLX for outgoing responses
Clientside /users/www-root/JBAJXBJABCJBJJHDLDHLKDJNJDNLX would become Serverside /images/banner.jpg for incoming requests, but only if signature/encryption could be verified.
Cheers, Kai