0

I am running DotNetNuke 7.2.2 Community Edition which by default returns all HTML-pages with

Cache-Control: private

in the response header. To generation of static HTML pages on the DotNetNuke platform typically takes 200-300 ms on our server, but when mixed with a caching proxy on basis of Apache HTTP Daemon v2.2 which caches pages, it only takes 20-30 ms when the page is in the cache of Apache.

The cache-control: private in the header can be ignored using

CacheEnable disk /
CacheRoot /path/to/disk/cache
CacheDirLevels 3
CacheDirLength 5
CacheIgnoreNoLastMod on
CacheStorePrivate on
CacheStoreNoStore on
CacheIgnoreCacheControl on # Needed!
CacheIgnoreQueryString off
CacheDefaultExpire 86400
CacheMaxFileSize 100000
CacheMaxExpire 172800

This works fine as long as no one access the website when authenticated. When working authenticated, the pages returned when you are authenticated are also cached and can provide a hook for a security breach.

When authenticated, the URL-s are still the same, so you can not filter on the URL to avoid caching taking place.

Is there any other way to convince Apache to not cache pages from DotNetNuke when logged on?

Guido Leenders
  • 4,232
  • 1
  • 23
  • 43

2 Answers2

1

My first thought was caching based on cookie as per this article: Apache caching based on cookie. But according to the answer on that article, you would need to explicitly add a no-cache header which may be possible to add to a skin token that is on every page to produce the header based on the Request.Authenticated flag.

Community
  • 1
  • 1
Fix It Scotty
  • 2,852
  • 11
  • 12
  • Thanks for thinking along, your hint on Header edit was very helpful. I've included the final solution in a separate answer, and your was really helpful, so I will check that one. – Guido Leenders May 26 '14 at 19:33
0

With help from @DotNetNuclear the following solution was built and found to drastically improve performance:

Change Default.aspx.cs on the DNN server to first of all ensure that all unauthenticated users have NoCache in their Response Headers. And authenticated users have cacheability set as follows:

            Response.Cache.SetCacheability(HttpCacheability.NoCache); // You can set host settings to 0. Is the same.
        }
        else
        {
                    // Unauthenticated users.
                    // MAKE CONFIGURABLE IN HOST SETTINGS.
                    Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);
                    //
                    // Allow proxies to cache for one day.
                    //
                    // MAKE CONFIGURABLE IN HOST SETTINGS.
                    Response.Cache.SetProxyMaxAge(new TimeSpan(24, 0, 0));
                    //
                    // Enforce not caching at client.
                    //
                    // MAKE CONFIGURABLE IN HOST SETTINGS.
                    Response.Cache.SetMaxAge(new TimeSpan(0, 0, 30));
        }

A request was logged to allow end user configuration of these changes. Now you can make a difference between authenticated (NoCache) and unauthenticated/public requests (ServerAndPrivate) using the following settings in Apache:

CacheEnable disk /
CacheRoot /var/cache/mod_cache
CacheDirLevels 2
CacheDirLength 4
# Do not overrule the default settings whether to cache.
# Can not be off, sorry.
CacheIgnoreNoLastMod on
#
# Use ServerAndPrivate since otherwise the Set-Cookie makes the cache
# being unused.
#
CacheStorePrivate on
CacheStoreNoStore on
#
# Ensure you set authenticatedcacheability on server to NoCache.
#
# Set to this off to allow logins.
CacheIgnoreCacheControl off
#
CacheIgnoreQueryString off
#
# Avoid cookies being put in cache.
# Use removal of the Server header as a sign that something is coming from cache.
# It requires Apache 2.4 to indicate that more nicely.
#
CacheIgnoreHeaders Set-Cookie Server
#
# Cache by default when not specified otherwise in last-modified or expiry date.
# In seconds.
CacheDefaultExpire 86400
CacheMaxFileSize 100000
#
# Always check every two days.
#
CacheMaxExpire 172800
# Disable caching on locations which we know to contain static content already
# cached by IIS.
CacheDisable ...some locations...

#
# Rewrite DNN caching.
#
#
# Set public instead of no-cache cahing on these specific files. IIS wants to
# use with max-age but without public. Probably since a cookie is involved, but that
# cookie is cleaned away in the cache.
#
SetEnvIfNoCase Request_URI "DependencyHandler\.axd$" rewrite_to_public_cache
SetEnvIfNoCase Request_URI "sb-client\.js$" rewrite_to_public_cache
SetEnvIfNoCase Request_URI "main\.js$" rewrite_to_public_cache
SetEnvIfNoCase Request_URI "inpage_linkid\.js$" rewrite_to_public_cache
SetEnvIfNoCase Request_URI "\.gif$" rewrite_to_public_cache
SetEnvIfNoCase Request_URI "\.png$" rewrite_to_public_cache
SetEnvIfNoCase Request_URI "\.jpg$" rewrite_to_public_cache
Header edit Cache-Control no-cache public env=rewrite_to_public_cache
Guido Leenders
  • 4,232
  • 1
  • 23
  • 43